PYQT5+openCV项目实战:微循环仪图片、视频记录和人工对比软件(附源码)


这是一个使用PYQT5编写的基于openCV的图片视频采集软件。
源代码:
链接:https://pan.baidu.com/s/1BtLGvmnfWBqo3tPlRmBQNQ?pwd=74s6
提取码:74s6

csnd下载源码

1.主要功能

播放微循环显微仪的实时视频,可以保存图片及短视频到本地硬盘;保存的图片以编号+日期时间命名;回查记录时,以类似资源管理器的方式查看,可以随意比较2张图片。

1.1主界面说明

在这里插入图片描述

按键功能说明:
①打开视频: 视频没有打开时,按下“打开视频”,打开实时图像,按钮文字变为“关闭视频”;这时再按键本按钮,关闭实时图像。
②拍照:截取实时画面到保存图片的位置。
③保存图片:将拍照的图片以编号+时间命名后,保存到硬盘。
④查看记录:打开“回查界面”。
⑤新增编号:增加列表中没有的名字,如果已经在列表中,可以在下拉列表中选择。

1.2回查记录界面说明

在这里插入图片描述

回查界面的左侧是一个2级的文件管理列表,以上图为例,de01、de02等等是编号,编号的子列表是图片,图片以 编号+日期时间命名,单击图片名称时,图片出现在浏览图片;双击图片名称,图片出现在比对图片。

2.主界面功能详解

2.1 摄像头操作

实时显示摄像头影像的原理就是一秒钟内读取超过24帧的图片并显示出来。具体操作就是设定一个40ms(一秒25帧,或者更小时间)的定时器,每40ms去读一次摄像头的图片,在固定区域显示,这样就可以看到流畅的视频。

从摄像头读取一帧图像并显示的代码

    def show_pic(self):
        #   1. 读取一帧图像
        success, frame=self.cap.read()
        if success:
            #   2.获取当前时间,选择字体
            datet = (datetime.datetime.now()).strftime("%Y-%m-%d_%H:%M:%S")  
            font = cv.FONT_HERSHEY_SIMPLEX
            #   3.微循环仪的分辨率是600 x 480,把图片放大到 720 x 540
            Image = cv.resize(frame,(720,540),interpolation=cv.INTER_CUBIC)
            #   4.在图片中加上时间戳
            Image= cv.putText(Image, datet, (10, 540-10), font, 0.5,  (0, 0, 255), 1, cv.LINE_AA)
            show = cv.cvtColor(Image, cv.COLOR_BGR2RGB)
            #   5.在PYQT5显示,需要转化为QPixmap格式
            self.showImage = QImage(show.data, show.shape[1], show.shape[0], QImage.Format_RGB888)
            self.vediolabel.setPixmap(QPixmap.fromImage(self.showImage))
            #   6.是否记录视频
            if self.IsVedioRecord:
                #   6.1 写入帧到视频文件中
                self.aviout.write(frame)  
                #   6.2 只能记录几秒钟的时长
                if   time.time() > self.recordStartTime:
                    self.IsVedioRecord = False
                    self.label_tip.setText("录像结束!  "+datet)
                    #   6.3务必释放摄像头
                    self.aviout.release() 

2.2拍照功能

按下“拍照”按键,就把当前的图像临时保存下来(还没有写入硬盘),名字是《编号+日期+时间.png》。

“拍照”按键对应的代码:

    def show_picA(self):
        #   1.变量self.showImage 中存放最近的图像,对此刻的图片进行临时保存,在拍照图片区域显示
        self.label.setPixmap(QPixmap.fromImage(self.showImage))
        self.recordImage = self.showImage
        datet = (datetime.datetime.now()).strftime("%Y-%m-%d_%H:%M:%S") 
        self.label_tip.setText("拍照成功!  "+datet)
        datet = (datetime.datetime.now()).strftime("%Y-%m-%d_%H-%M-%S") 
        #   2.生成图片名称
        self.saveName = self.nameBox.currentText() +'_'+ datet + '.png'

2.3保存图片

拍照后,觉得这个图片值得保存,按下“保存图片”按键,将图片保存到硬盘。

“保存图片”按键对应的代码:

    def save_pic_to_userfolder(self):
        if len(self.saveName) == 0:
            return
        datet = (datetime.datetime.now()).strftime("%Y-%m-%d_%H:%M:%S") 
        self.label_tip.setText("图片保存成功!  "+datet)
        self.savePath = self.Code51_dir+'/ymtdata/'+self.nameBox.currentText()+'/'+self.saveName
        self.recordImage.save(self.savePath, 'PNG')

2.4录制短视频

录制视频的代码在2.1摄像头操作,“拍视频”按键的功能是:创建视频流对象,设置录制时长,打开录制开关。

“拍视频”按键对应的代码:

    def start_vedio_record(self):
        #   1.设置视频编码格式
        FRAME_WIDTH = 640
        FRAME_HEIGHT = 480
        FPS = 10
        if not self.IsVedioRecord:
            #   2.生成需要保存的视频文件名称
            datet = (datetime.datetime.now()).strftime("%Y-%m-%d_%H-%M-%S") 
            self.vedioName = self.Code51_dir+'/ymtdata/'+self.nameBox.currentText()+'/'   \
                                        +self.nameBox.currentText()+'_'+datet+'.avi'                                        
            #   3.创建视频流对象
            fourcc = cv.VideoWriter_fourcc(*'XVID')
            self.aviout = cv.VideoWriter(self.vedioName, fourcc, FPS, (int(FRAME_WIDTH), int(FRAME_HEIGHT)))
            #   4.启动录制开关
            self.IsVedioRecord = True
            #   5.设定录制时长为5秒
            self.recordStartTime = time.time()+5.0
            self.label_tip.setText("录像开始!  "+datet)
        pass

录制的视频实例:

hwd_2021-10-19_09-19-46

de01_2021-10-19_09-34-49

2.5查看记录

软件所在目录有个《ymtdata》,下面存放了各个编号的子文件夹,子文件夹里面存放图片或视频。“查看记录”按键是打开新的窗口(子界面),子界面的代码在下一章讲述。

“查看记录”按键对应的代码:

    def open_ViewDialog(self):  
        #   1.打开查看图片的子窗口,需要关闭摄像头,退出后需要手动打开
        if  self.IsTimerStart:
            self.timer_camera.stop()
            self.OpenCamera.setText("打开摄像头")
            self.IsTimerStart = False          
        Dlg = ViewDlg(self)
        #   2. 显示窗口
        Dlg.exec_()

2.6新建名称

新建一个编号,这个编号会出现在下拉条里面,还会创建一个子文件夹。

“新建名称”按键对应的代码:

    def input_name(self):    
        #1. 创建文件夹 
        text, ok = QInputDialog.getText(self, '输入名称', '输入名称:')
        if ok:
            datet = (datetime.datetime.now()).strftime("%Y-%m-%d_%H:%M:%S") 
            self.label_tip.setText(str(text)+datet)   
            self.savePath = self.Code51_dir+'/ymtdata'+'/'+str(text)
            #2. 判断文件夹是否已经存在,如果是,不创建 
            if not os.path.exists(self.savePath):
                os.mkdir(self.savePath)    #创建 空文件夹  
                #3. 添加到nameBox
                self.nameBox.addItem(text)  
                #4.将 新建项 作为 选择项
                self.nameBox.setCurrentIndex(self.nameBox.count()-1)

3.子界面功能详解

打开子界面,会在界面的左侧生成一个2级的文件管理列表,图片显示区有左右两个区域,左边是浏览图片,单击时,图片或视频静态显示在本区域;双击文件,如果是图片文件,则在右边的对比图片区域显示,如果是视频,则在左边播放视频。

3.1 创建文件管理列表

遍历《ymtdata》下面的子文件夹和文件,结构比较单一。
在这里插入图片描述


    def __init__(self, parent=None):
        super(ViewDlg, self).__init__(parent)
        self.setupUi(self)
        ......
        #2.1    根名称
        root1=QTreeWidgetItem(self.tree)
        root1.setText(0,'图片浏览')
        if os.path.exists(self.rootDir):       
            self.CreateTree( os.listdir(self.rootDir),root1 ,self.rootDir )
        #只展开第一级
        self.tree.expandToDepth(0)  
        .......
        pass
    def CreateTree(self, dirs, root, path):
        for i in dirs:
            path_new = path + '/' + i
            if os.path.isdir(path_new):
                child = QTreeWidgetItem(root)
                child.setText(0,i)
                child.setIcon(0,QIcon(":/{0}.png".format("Folder")))
                dirs_new = os.listdir(path_new)
                self.CreateTree(dirs_new, child, path_new)
            else:
                if '.png' in i  or '.avi' in i:
                    child = QTreeWidgetItem(root)
                    child.setText(0,i)
                    if '.png' in i:
                        child.setIcon(0,QIcon(":/{0}.png".format("jpg32")))
                    elif '.avi' in i:
                        child.setIcon(0,QIcon(":/{0}.png".format("vedio32")))

3.2单击文件

    def onClicked(self, item): 
        item=self.tree.currentItem()
        if '.png' in item.text(0) :     #1.如果是图片,在左侧显示
            self.fileName =self.rootDir +'/'+item.parent().text(0)+'/'+ item.text(0) 
            self.label_view.setPixmap(QPixmap(self.fileName))
        elif '.avi' in item.text(0) :   #2. 如果是视频,只读取第一帧 显示
            self.fileName =self.rootDir +'/'+item.parent().text(0)+'/'+ item.text(0) 
            self.cap = cv.VideoCapture(self.fileName)
            success, frame = self.cap.read()
            if success:
                Image = cv.resize(frame,(720,540),interpolation=cv.INTER_CUBIC)
                show = cv.cvtColor(Image, cv.COLOR_BGR2RGB)
                showImage = QImage(show.data, show.shape[1], show.shape[0], QImage.Format_RGB888)
                self.label_view.setPixmap(QPixmap.fromImage(showImage))
            self.cap.release()

3.3双击文件

    def onTreeDoubleClicked(self,qmodeLindex):     #对工程列表中的文件双击  
        item=self.tree.currentItem()
        if '.png' in item.text(0) :     #1.如果是图片,在右侧显示
            self.fileName =self.rootDir +'/'+item.parent().text(0)+'/'+ item.text(0) 
            self.label_cmp.setPixmap(QPixmap(self.fileName))
        elif  '.avi' in item.text(0) : #2. 如果是视频,左侧播放视频
            self.fileName =self.rootDir +'/'+item.parent().text(0)+'/'+ item.text(0) 
            self.cap = cv.VideoCapture(self.fileName)
            #打开视频,打开定时器
            self.timer_camera = QTimer(self)
            self.timer_camera.timeout.connect(self.show_pic)
            self.timer_camera.start(30)
            self.isTimerOn=True
posted @ 2022-06-30 15:39  汉塘阿德  阅读(87)  评论(0编辑  收藏  举报  来源