使用Python处理ADC激光测距数据并绘制为图片
说明
主要是将ADC激光测距叠加后的1024Byte数据绘制为图片,便于直观的分析与观察
一、定义全局变量变
import matplotlib.pyplot as plt
import os
import shutil
PeakValue_y = 0 #峰值
PaekIndex_x = 0 #峰值索引
PeakValuePer50 = 0 # 峰值百分比
PeakValuePer60 = 0
PaekIndex_LeftRight_Gap = 50 #峰值左右间隔
Axis_x = list() #横坐标
Axis_y = list() #纵坐标
# StaInfoFileName = "StaInfo.txt" #统计文件
StaInfoFileIndex = 0 #统计信息数量
#处理原始数文件信息
HandlerDataDir = "HandlerData" #目录
HandlerDataName = "COM19-115200-2023-06-09-16-29-27-阳光天空" #文件名
HandlerDataExtension = ".log" #扩展名
HandlerDataDirName = HandlerDataDir + "/"+ HandlerDataName + HandlerDataExtension #目录 + 文件名 + 扩展名
#处理数据后统计信息
StaInfo_Dir = HandlerDataName #目录
StaInfo_DirName = StaInfo_Dir + "/" + HandlerDataName + ".txt" #目录 + 文件名 + 扩展名
ADC_ORG = {}
AbstractData = \
(
"ADC Data......Level:",
"FloorNoise:",
"DataPeak :",
"MaxPoint :",
"FullNum :",
"PulseValid:",
"ZeroPoint :",
"ADC Meas Dist OK ===> :"
)
二、分离键值对
#数据处理
def Abstract_Data_Handler(lineStr, str):
if str in lineStr:
new = "]" + str
index = lineStr.find(new)
if index != -1:
return lineStr[index + 1:]
else:
return ""
else:
return ""
#分离键值对
def Split_KeyValue():
global ADC_ORG
global PeakValue_y
global PaekIndex_x
PeakValue_y = 0
PaekIndex_x = 0
i= 0
for xKey, yVal in ADC_ORG.items():
if i <= 1023:
Axis_x.append(int(xKey))
Axis_y.append(int(yVal))
val = int(yVal)
if val > PeakValue_y:
PeakValue_y = val
PaekIndex_x = int(xKey)
# else:
# print("%s==>%s" % (str(xKey), str(yVal)), end='')
i = i +1
三、获取图片名称
#获取图片名称
def GetImageName():
global ADC_ORG
str1DataTime = "DataTime-"
str2LevelCount = "LevelCount-"
str3MeasDist = "0000dm"
atcFlag = str(ADC_ORG[1029]).strip()
if "PulseValid:1" in atcFlag:
str1DataTime = ADC_ORG[1032].strip()
distStr = ADC_ORG[1031].strip()
if "ADC Meas Dist OK ===> :" in distStr:
index = distStr.find(":")
if index != -1:
str3MeasDist = distStr[index + 1 : ] + "dm"
elif "PulseValid:0" in atcFlag:
str1DataTime = ADC_ORG[1031].strip()
levelCount = ADC_ORG[1024].strip()
if "ADC Data......Level:" in levelCount:
index = levelCount.find("Level:")
if index != -1:
str2LevelCount = str(levelCount[index:]).replace(":", "").replace(" ", "-").replace("\n", "") + "-"
resStr = str(str1DataTime + str2LevelCount + str3MeasDist).strip().replace("\n", "")
# print("\n\nImageName:", resStr)
return resStr
四、获取标题和FigText
#清除缓存信息
def ClearDatMemory():
ADC_ORG.clear()
Axis_x.clear()
Axis_y.clear()
# 获取FigText
def GetFigText():
global ADC_ORG
#档位分析信息
distStr = "\n"
fontStr = str(ADC_ORG[1024]) + str(ADC_ORG[1025]) + str(ADC_ORG[1026]) + \
str(ADC_ORG[1027]) + str(ADC_ORG[1028]) + str(ADC_ORG[1029]) + \
str(ADC_ORG[1030])
#测量是否成功
atcFlag = ADC_ORG[1029]
if "PulseValid:1" in atcFlag:
distStr = str(ADC_ORG[1031]) + "\n"
resStr = str(fontStr + distStr).strip()
# print("FigText:", resStr + "\n")
return resStr
#获取标题
def GetTitleText():
global PaekIndex_x
global PeakValue_y
global PaekIndex_LeftRight_Gap
#峰值左右范围
xleft = PaekIndex_x - PaekIndex_LeftRight_Gap
xright = PaekIndex_x + PaekIndex_LeftRight_Gap
if xleft < 0:
xleft = 0
if xright > 1023:
xright = 1023
resStr = "center:%s xleft:%s xright:%s" % (str(PaekIndex_x), str(xleft), str(xright))
# print("TitleText:", resStr)
return resStr, xleft, xright
五、更新统计信息文件
#更新统计信息文件
def UpdateStatisticsInfoFile(txt):
global StaInfoFileIndex
global ADC_ORG
# 创建目录及统计文件
if StaInfoFileIndex == 0:
if os.path.isdir(StaInfo_Dir):#目录是否存在
if os.path.isfile(StaInfo_DirName):#文件是否存在
try:
os.remove(StaInfo_DirName)
except FileNotFoundError:
print("Remove StaInfo DirName Fail...", end='')
else:
try:
with open(StaInfo_DirName, 'w'):#创建文件
pass
except FileNotFoundError:
print("Creat StaInfo DirName Fail...", end='')
else:
os.mkdir(StaInfo_Dir)
with open(StaInfo_DirName, 'a+', encoding='utf-8') as file:
StaInfoFileIndex = StaInfoFileIndex + 1
# 写入统计信息
peak = str(ADC_ORG[1026]).strip()
strTxt = '[{}] '.format(int(StaInfoFileIndex)) + txt
resTxt = strTxt + " ==> " + peak + "\n"
file.write(resTxt)
print(resTxt, end='')
六、绘制图像
#绘制图像
def DrawImage():
global PeakValuePer50
global PeakValuePer60
global StaInfoFileIndex
global ADC_ORG
pic_name = GetImageName() + ".png"
figTxt = GetFigText()
titleTxt, xleft, xright = GetTitleText()
PeakValuePer50 = PeakValue_y * 0.5
PeakValuePer60 = PeakValue_y * 0.6
# plt.figure(figsize=(18, 10))
plt.figure(figsize=(12, 8))
plt.title(titleTxt)
plt.figtext(0.15, 0.7, figTxt, ha="left", va="center")
plt.xlabel("Sampling Point")
plt.ylabel("Superposition Data")
plt.axvline(xleft, color="green", linestyle="--")
plt.axvline(xright, color="green", linestyle="--")
plt.axvline(PaekIndex_x)
plt.axhline(PeakValue_y, color="red")
plt.axhline(int(PeakValuePer50), color="blue")
plt.axhline(int(PeakValuePer60), color="blue")
plt.text(500, int(PeakValue_y) - 8, 'Peak:{}'.format(int(PeakValue_y)), color="red", ha='left', va='center')
plt.text(500, int(PeakValuePer50) - 8, 'Peak50%:{}'.format(int(PeakValuePer50)), color="blue", ha='left', va='center')
plt.text(500, int(PeakValuePer60) - 8, 'Peak60%:{}'.format(int(PeakValuePer60)), color="blue", ha='left', va='center')
plt.plot(Axis_x, Axis_y, 'ro', linewidth=2)
# manager = plt.get_current_fig_manager() # 将图形窗口最大化
# manager.window.wm_state('zoomed')
# 删除目录及内容重新创建
# if StaInfoFileIndex == 0:
# if os.path.isdir(HandlerDataName):
# shutil.rmtree(HandlerDataName)
# os.mkdir(HandlerDataName)
#删除目录中所有信息
if StaInfoFileIndex == 0:
if os.path.isdir(HandlerDataName):#目录存在
for item in os.listdir(HandlerDataName):
name = os.path.join(HandlerDataName, item)
if os.path.isfile(name):#目录
os.remove(name)
elif os.path.isdir(name):#文件
shutil.rmtree(name)
else:
os.mkdir(HandlerDataName)
#保存图标
pic_name_dir = HandlerDataName + '/' + pic_name
plt.savefig(pic_name_dir, dpi=300, bbox_inches='tight')
UpdateStatisticsInfoFile(pic_name)
plt.close()
ClearDatMemory()
#是否要绘制图像
def Judge_GenerateImage():
global PeakValue_y
if PeakValue_y > 50:
return True
return False
七、读取文件内容并解析
#读取文件内容并解析
def Read_File_ContentText(name):
global ADC_ORG
global StaInfoFileIndex
with open(name, 'r', encoding='utf-8') as file:
headflag = 0
datIndexCount = 0
ADC_ORG.clear()
maxdatIndex = 1032
StaInfoFileIndex = 0
for line in file:
if headflag == 0:
if "[0000]" in line: #寻找开始索引
index = line.find("[0000]")
if index != -1:
ClearDatMemory()
key = line[index + 1 : index + 5]
val = line[index + 6 : ]
ADC_ORG[key] = val
headflag = 1
datIndexCount = 0
else:
datIndexCount = datIndexCount + 1
numHead = '[%04u]' % datIndexCount
if datIndexCount <= 1023: #1024个数据
if numHead in line:
index = line.find(numHead)
if index != -1:
key = line[index + 1: index + 5].strip()
val = line[index + 6:].strip()
ADC_ORG[key] = val.strip()
else:
ClearDatMemory()
headflag = 0
else:
if datIndexCount == 1029:#确认最大保存索引
if "PulseValid:1" in line:
maxdatIndex = 1032
elif "PulseValid:0" in line:
maxdatIndex = 1031
if datIndexCount == (maxdatIndex - 1):
#获取日期
start = line.find("[")
end = line.find("]")
if start != -1 and end != -1:
date = line[start + 1:end].replace(" ", "-").replace(":", "-")+"-"
if datIndexCount >= maxdatIndex:
ADC_ORG[maxdatIndex] = date #最后保存日期
Split_KeyValue()
if Judge_GenerateImage() == True:#是否要绘制图片
DrawImage()
headflag = 0
ClearDatMemory()
continue
# 档位分析信息
str = AbstractData[datIndexCount - 1024]
reStr = Abstract_Data_Handler(line, str)
ADC_ORG[datIndexCount] = reStr
八、函数入口(主函数)
def main():
if os.path.isfile(HandlerDataDirName):#文件存在
Read_File_ContentText(HandlerDataDirName)
if __name__ == "__main__":
main()
九、测试结果
原始文件信息
处理后结果展示