使用Python处理ADC激光测距数据并绘制为图片

该代码主要处理ADC激光测距的1024Byte数据,绘制图像以方便分析。它定义了全局变量,分离键值对,获取图片名称,更新统计信息文件,并使用matplotlib库绘制图像,包括峰值、比例线和相关信息文本。此外,还包含一个主函数来读取和解析文件内容,以及判断是否生成图像。
摘要由CSDN通过智能技术生成

说明

主要是将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()
    

九、测试结果

原始文件信息
在这里插入图片描述在这里插入图片描述




处理后结果展示
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值