使用Python处理ADC激光测距数据并绘制为图片
- 说明
- 一、定义全局变量变
- 二、保存和清空原始数据
- 三、拆分原始数据为键值对
- 四、获取标题、FigText、更新统计信息文件
- 五、生成图片
- 六、处理原始数据文件
- 七、主函数入口
- 八、测试结果
说明
1. 主要是将ADC激光测距叠加后的1024Byte数据绘制为图片,便于直观的分析与观察
一、定义全局变量变
import os
import shutil
import matplotlib.pyplot as plt
# 原始数据
OrgDataDir = 'DataHandlerDir' #原始数据目录
OrgDataName = 'COM3-115200-2023-08-03-14-22-49-650m' #原始文件名称
OrgDataExtension = '.log' #原始文件拓展名
OrgDataFullDirNameExt = OrgDataDir + '/' + OrgDataName + OrgDataExtension #全路径
OrgDataFilesGroup = list()
# 处理后数据
CreatDataFatherDir = 'ImageCreatDir' #目录
CreatDataDir = OrgDataName
CreatDataName = OrgDataName
CreatDataExtension = '.txt' #统计文件扩展名
CreatDataNameExtension = CreatDataName + CreatDataExtension
CreatDataImageFullDir = CreatDataFatherDir + '/' + CreatDataDir
CreatDataStaFullDirNameExt = CreatDataFatherDir + '/' + CreatDataDir + '/' + CreatDataName + CreatDataExtension
# FigText序号范围
FigTextStartIndex = 1024
FigTextEndIndex = 1030
# 峰值及索引
OrgDataPeakValue = 0 # 峰值
OrgDataPeakIndex = 0 # 峰值索引
OrgDataPeakValue50 = 0 # 峰值50%
OrgDataPeakValue60 = 0 # 峰值60%
OrgDataPeakIndexGap = 50 # 峰值索引间隔
OrgDataPeakIndexLeft = 0 # 峰值索引左值
OrgDataPeakIndexRigth = 0 # 峰值索引右值
AtcDataHeaderStr = '[0000]' # 有效数据头
OrgDataValSize = 1024 # ADC数据项大小
OrgDataMemory = {} # 原始数据缓存
UpdateImageCount = 0 # 图片计数
AxisX = list() # 横坐标
AxisY = list() # 纵坐标
二、保存和清空原始数据
# 保存原始数据
def Store_OrgData_KeyVal(key, val):
global OrgDataMemory
OrgDataMemory[key] = val
# 清空原始数据缓存
def Clear_OrgData_Memory():
global OrgDataMemory
global AxisX
global AxisY
global OrgDataPeakValue
global OrgDataPeakIndex
global OrgDataPeakValue60
global OrgDataPeakValue50
global OrgDataPeakIndexLeft
global OrgDataPeakIndexRigth
global UpdateImageCount
OrgDataMemory.clear()
AxisX.clear()
AxisY.clear()
OrgDataPeakValue = 0
OrgDataPeakIndex = 0
OrgDataPeakValue60 = 0
OrgDataPeakValue50 = 0
OrgDataPeakIndexLeft = 0
OrgDataPeakIndexRigth = 0
三、拆分原始数据为键值对
# 拆分键值对
def Split_OrgData_KeyVal():
global OrgDataMemory
global OrgDataPeakValue
global OrgDataPeakIndex
global OrgDataPeakValue50
global OrgDataPeakValue60
global OrgDataPeakIndexGap
global OrgDataPeakIndexLeft
global OrgDataPeakIndexRigth
global AxisX
global AxisY
i = 0
peakVal = 0
for xKey, yVal in OrgDataMemory.items():
AxisX.append(int(xKey))
AxisY.append(int(yVal))
# 寻找峰值及索引
peakVal = int(yVal)
if peakVal > OrgDataPeakValue:
OrgDataPeakValue = peakVal
OrgDataPeakIndex = int(xKey)
i += 1
if i >= OrgDataValSize:
OrgDataPeakValue60 = OrgDataPeakValue * 0.6 # 峰值50%
OrgDataPeakValue50 = OrgDataPeakValue * 0.5 # 峰值60%
# 峰值左间隔
OrgDataPeakIndexLeft = OrgDataPeakIndex - OrgDataPeakIndexGap
if OrgDataPeakIndexLeft < 0:
OrgDataPeakIndexLeft = 0
# 峰值右间隔
OrgDataPeakIndexRigth = OrgDataPeakIndex + OrgDataPeakIndexGap
if OrgDataPeakIndexRigth > OrgDataValSize - 1:
OrgDataPeakIndexRigth = OrgDataValSize - 1
return
四、获取标题、FigText、更新统计信息文件
# 获取FigText
def GetFigText():
global OrgDataMemory
global FigTextStartIndex
global FigTextEndIndex
resStr = ''
for i in range(FigTextStartIndex, FigTextEndIndex + 1):
txt = OrgDataMemory[str(i)]
resStr += txt + '\n'
# print("GetFigText:", resStr)
return resStr
# 获取标题
def GetTitleText():
global OrgDataPeakIndex
global OrgDataPeakIndexLeft
global OrgDataPeakIndexRigth
global OrgDataPeakValue
resStr = "xCenter:%s xLeft:%s xRight:%s Peak:%s" % ( \
str(OrgDataPeakIndex), \
str(OrgDataPeakIndexLeft), \
str(OrgDataPeakIndexRigth), \
str(OrgDataPeakValue))
# print("TitleText:", resStr)
return resStr
# 获取图片名称
def Get_Image_Name():
global OrgDataMemory
global FigTextEndIndex
txtStr = str(OrgDataMemory[str(FigTextEndIndex)])
index = txtStr.find('Gears:')
if index != -1:
name = txtStr[index:].strip().replace(':', '').replace(' ', '-')
else:
name = 'Gears0-Superpos0-Dist0dm'
picName = str(OrgDataMemory[str(FigTextEndIndex + 1)]) + '-' + name
return picName
# 更新统计信息
def Update_StaInfo(staFileFullName, txt):
global OrgDataPeakValue
with open(staFileFullName, 'a+', encoding='utf-8') as file:
# strTxt = '[{}] '.format(int(UpdateImageCount)) + txt
strTxt = '[%04u] ' % UpdateImageCount + txt
resTxt = strTxt + " ==> Peak:" + str(OrgDataPeakValue) + "\n"
file.write(resTxt)
print(resTxt, end='')
五、生成图片
# 生成图片
def OrgData_CreateImage(staFileDir, staFileFullName):
global AxisX
global AxisY
global OrgDataPeakIndex
global OrgDataPeakIndexLeft
global OrgDataPeakIndexRigth
global OrgDataPeakValue
global OrgDataPeakValue50
global OrgDataPeakValue60
global CreatDataImageFullDir
global UpdateImageCount
Split_OrgData_KeyVal()
plt.figure(figsize=(12, 8))
plt.title(GetTitleText())
plt.xlabel("Sampling Point")
plt.ylabel("Superposition Data")
plt.plot(AxisX, AxisY, 'ro', linewidth=2)
plt.axvline(OrgDataPeakIndex)
plt.axvline(OrgDataPeakIndexLeft, color="green", linestyle="--")
plt.axvline(OrgDataPeakIndexRigth, color="green", linestyle="--")
plt.axhline(OrgDataPeakValue, color="red")
plt.axhline(int(OrgDataPeakValue50), color="blue")
plt.axhline(int(OrgDataPeakValue60), color="blue")
plt.text(600, int(OrgDataPeakValue), 'Peak={}'.format(int(OrgDataPeakValue)), fontsize=16, fontweight='bold', color="black", ha='left', va='center')
plt.text(300, int(OrgDataPeakValue50), '50%Peak={}'.format(int(OrgDataPeakValue50)), fontsize=16, fontweight='bold', color="black", ha='left', va='center')
plt.text(600, int(OrgDataPeakValue60), '60%Peak={}'.format(int(OrgDataPeakValue60)), fontsize=16, fontweight='bold', color="black", ha='left', va='center')
plt.figtext(0.15, 0.7, GetFigText(), color='blue', fontsize=12, ha="left", va="center")
UpdateImageCount += 1
picName = Get_Image_Name()
serial = '[%04u]' % UpdateImageCount
picDirName = staFileDir + '/' + serial + picName + ".png"
plt.savefig(picDirName, dpi=300, bbox_inches="tight")
Update_StaInfo(staFileFullName, picName)
plt.close()
Clear_OrgData_Memory()
六、处理原始数据文件
# 处理原始数据文件
def File_OrgData_Handler(orgDatFullName, staFileDir, staFileFullName):
global AtcDataHeaderStr
global FigTextEndIndex
with open(orgDatFullName, 'r', encoding='utf-8') as fileHander: # 打开文件
actDataHeaderFlg = 0 # 有效数据头
indexCount = 0 # 索引计数
for lineTxet in fileHander: # 读取一行数据
if actDataHeaderFlg == 0: # 数据头无效
if AtcDataHeaderStr in lineTxet: # 包含数据头
startIndex = lineTxet.find(AtcDataHeaderStr) # 数据头位置
if startIndex != -1: # 位置有效
endIndex = lineTxet.find(']', startIndex)
if endIndex != -1:
key = lineTxet[startIndex + 1: endIndex].strip() # 截取数据
val = lineTxet[endIndex + 1:].strip()
if key.isdigit() == True and val.isdigit() == True: # 都为数字
Clear_OrgData_Memory() # 清空缓存
Store_OrgData_KeyVal(key, val) # 保存数据
actDataHeaderFlg = 1 # 数据头有效
indexCount = 0
else:
indexCount = indexCount + 1 # 计数加1
indexHeader = '[%04u]' % indexCount
if indexCount <= (OrgDataValSize - 1): # ADC数据0~1023
if indexHeader in lineTxet: # 包含ADC数据索引
start = lineTxet.find(indexHeader) # 索引有效
end = lineTxet.find(']', start)
if start != -1 and end != -1:
key = lineTxet[start + 1: end].strip() # 截取数据去掉前后空格
val = lineTxet[end + 2:].strip()
if key.isdigit() == True and val.isdigit() == True: # 都为数字
Store_OrgData_KeyVal(key, val) # 保存数据
continue
Clear_OrgData_Memory()
actDataHeaderFlg = 0
indexCount = 0
else: # 其他数据1024以后
start = lineTxet.find(']')
if start != -1: # 索引有效
val = lineTxet[start + 1:].strip()
if len(val) != 0 and val != '': # 有内容
Store_OrgData_KeyVal(str(indexCount), val) # 保存数据
if val.find('ADC Meas Complete ==> Gears:') != -1: # 结束标准
timesTick = lineTxet[1: start].strip().replace(' ', '-').replace(':', '-') # 截取数据
Store_OrgData_KeyVal(str(indexCount + 1), timesTick) # 保存数据
FigTextEndIndex = indexCount
actDataHeaderFlg = 0
indexCount = 0
# name = os.path.splitext(os.path.basename(dirName))[0]
# dir = os.path.join(CreatDataFatherDir, name)
if os.path.exists(staFileDir):
OrgData_CreateImage(staFileDir, staFileFullName)
else:
indexCount = indexCount - 1
else:
Clear_OrgData_Memory()
actDataHeaderFlg = 0
indexCount = 0
七、主函数入口
# 删除目录内容
def Delete_Directory_Content(dir):
if os.path.exists(dir) == True: # 目录存在
for item in os.listdir(dir): # 目录中内容
name = os.path.join(dir, item) # 拼接完整路径
if os.path.isfile(name):
os.remove(name) # 删除目录
elif os.path.isdir(name):
shutil.rmtree(name) # 删除文件
# 判断基本目录
def Judg_BasicDir_Info(datDir, creatDir):
res = 0
if not os.path.exists(datDir): # 目录不存在
print(datDir, "Directory No Exists, ", end='')
os.mkdir(datDir) # 创建目录
print("Create Successful......")
res = 1
if not os.path.exists(creatDir): # 目录不存在
print(creatDir, "Directory No Exists, ", end='')
os.mkdir(creatDir) # 创建目录
print("Create Successful......")
res = 2
return res
# 创建图片目录和统计文件
def Create_DataImage_DirFile(dir, name):
if not os.path.exists(dir): # 图片目录不存在
os.mkdir(dir)
else:
Delete_Directory_Content(dir)
dirName = os.path.join(dir, name)
open(dirName, 'a').close() # 创建统计文件
print('dirName:', dirName)
# 获取所有原始数据文件
def Get_OrgData_FilesGroup(dir, extName):
res = 1
fileGroup = list()
fileList = os.listdir(dir) # 获取目录中内容
for file in fileList:
if file.endswith(extName) == True: # 指定后缀名
fullName = os.path.join(dir, file) # 拼接名称
fileGroup.append(fullName) # 保存名称
res = 0
count = 0
for file in fileGroup:
if os.path.exists(file):
count += 1
print('[%04u] %s' % (count, file))
return res, fileGroup
#只处理 OrgDataFullDirNameExt原始文件数据
def Function_Option_Handler1():
global OrgDataFullDirNameExt
global CreatDataImageFullDir
global CreatDataNameExtension
if os.path.isfile(OrgDataFullDirNameExt) == True: # 原始数据文件存在
Create_DataImage_DirFile(CreatDataImageFullDir, CreatDataNameExtension) # 创建图片目录和统计文件成功
File_OrgData_Handler(OrgDataFullDirNameExt, CreatDataImageFullDir, CreatDataStaFullDirNameExt)
else:
print(OrgDataFullDirNameExt, "OrgDat File No Exists......")
#处理OrgDataDir目录下所有原始文件数据
def Function_Option_Handler2():
global OrgDataFilesGroup
global CreatDataExtension
global OrgDataDir
global OrgDataExtension
res, OrgDataFilesGroup = Get_OrgData_FilesGroup(OrgDataDir, OrgDataExtension)
if res == 0 and len(OrgDataFilesGroup) > 0:
for orgFile in OrgDataFilesGroup:
name = os.path.splitext(os.path.basename(orgFile))[0] # 名称
dir = os.path.join(CreatDataFatherDir, name) # 拼接目录
Create_DataImage_DirFile(dir, name + CreatDataExtension)
File_OrgData_Handler(orgFile, dir, os.path.join(dir, name + CreatDataExtension))
# 主函数入口
def main():
global CreatDataFatherDir
global OrgDataDir
if Judg_BasicDir_Info(OrgDataDir, CreatDataFatherDir) == 0: # 基本目录存在否
Function_Option_Handler1()
# Function_Option_Handler2()
else:
print("Basic Directory Creat Successful......")
print("OrgData Handler Complete......")
if __name__ == "__main__":
main()
八、测试结果
原始数据