基于Python PYQT5 编写相机定时采集图像及手动采集
版本介绍
Python 3.6
pyqt5 5.15.4
pyqt5-tools 5.15.4.3.2
另外就是常用的cv2和numpy包
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5 import QtCore, QtGui, QtWidgets
import cv2
import numpy as np
from datetime import datetime
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import threading
from PyCameraList.camera_device import test_list_cameras, list_video_devices, list_audio_devices
Py文件是使用QT Designer文件转换后,在其中进行编程。
注意:QT Designer工具只用了布局按钮等控件,具体控件的执行代码在py文件中编程实现
布局如上图所示,可以实现的功能:
- 查询电脑课使用的相机设备,显示在右侧的文本框内,根据显示的内容确定需要打开的相机序号
- 将获取的序号填入选择相机右边的文本框内
- 可以设置采集图像的间隔,单位是秒
- 选择储存地址
- 手动采集模式下,需要先点击开启相机,点击手动拍摄,点击一次采集一张图像,图像储存以采集时间命名
- 定时拍摄下,间隔固定的时间采集,后自动储存到选择的文件夹内。
源代码:
代码可直接运行
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'camera_capture.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5 import QtCore, QtGui, QtWidgets
import cv2
import numpy as np
from datetime import datetime
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import threading
from PyCameraList.camera_device import test_list_cameras, list_video_devices, list_audio_devices
class Ui_MainWindow(object):
def __init__(self):
super().__init__()
self.setupUi(MainWindow)
self.action()
# self.choose_camera.clicked.connect(self.choose_C)
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1079, 612)
MainWindow.setMinimumSize(QtCore.QSize(0, 0))
MainWindow.setMaximumSize(QtCore.QSize(33333, 33333))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.opencamera_time = QtWidgets.QPushButton(self.centralwidget)
self.opencamera_time.setGeometry(QtCore.QRect(720, 490, 131, 51))
self.opencamera_time.setToolTipDuration(1)
self.opencamera_time.setObjectName("opencamera_time")
self.closecamera = QtWidgets.QPushButton(self.centralwidget)
self.closecamera.setGeometry(QtCore.QRect(880, 420, 131, 51))
self.closecamera.setToolTipDuration(1)
self.closecamera.setObjectName("closecamera")
self.delaytime = QtWidgets.QLineEdit(self.centralwidget)
self.delaytime.setGeometry(QtCore.QRect(881, 280, 61, 31))
self.delaytime.setObjectName("delaytime")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(710, 280, 161, 31))
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setObjectName("label")
self.label_2 = QtWidgets.QPushButton(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(720, 340, 131, 51))
self.label_2.setToolTipDuration(1)
self.label_2.setObjectName("closecamera")
self.imagefiledir = QtWidgets.QLineEdit(self.centralwidget)
self.imagefiledir.setGeometry(QtCore.QRect(880, 350, 141, 31))
self.imagefiledir.setObjectName("imagefiledir")
self.label_3 = QtWidgets.QLabel(self.centralwidget)
self.label_3.setGeometry(QtCore.QRect(630, 70, 61, 31))
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.label_4 = QtWidgets.QLabel(self.centralwidget)
self.label_4.setGeometry(QtCore.QRect(630, 280, 71, 31))
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.label_4.setFont(font)
self.label_4.setObjectName("label_4")
self.label_5 = QtWidgets.QLabel(self.centralwidget)
self.label_5.setGeometry(QtCore.QRect(630, 350, 61, 31))
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.label_5.setFont(font)
self.label_5.setObjectName("label_5")
self.imageshow = QtWidgets.QLabel(self.centralwidget)
self.imageshow.setGeometry(QtCore.QRect(30, 90, 561, 401))
self.imageshow.setObjectName("imageshow")
self.find_camera = QtWidgets.QPushButton(self.centralwidget)
self.find_camera.setGeometry(QtCore.QRect(720, 60, 131, 51))
self.find_camera.setToolTipDuration(1)
self.find_camera.setObjectName("find_camera")
self.choose_camera = QtWidgets.QPushButton(self.centralwidget)
self.choose_camera.setGeometry(QtCore.QRect(720, 160, 131, 51))
self.choose_camera.setToolTipDuration(1)
self.choose_camera.setObjectName("choose_camera")
self.camera_number = QtWidgets.QLineEdit(self.centralwidget)
self.camera_number.setGeometry(QtCore.QRect(880, 170, 141, 31))
self.camera_number.setText("")
self.camera_number.setObjectName("camera_number")
self.camera_list = QtWidgets.QLineEdit(self.centralwidget)
self.camera_list.setGeometry(QtCore.QRect(880, 70, 141, 31))
self.camera_list.setText("")
self.camera_list.setPlaceholderText("")
self.camera_list.setObjectName("camera_list")
self.label_6 = QtWidgets.QLabel(self.centralwidget)
self.label_6.setGeometry(QtCore.QRect(950, 280, 71, 31))
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.label_6.setFont(font)
self.label_6.setObjectName("label_6")
self.manne_camera = QtWidgets.QPushButton(self.centralwidget)
self.manne_camera.setGeometry(QtCore.QRect(880, 490, 131, 51))
self.manne_camera.setToolTipDuration(1)
self.manne_camera.setObjectName("manne_camera")
self.opencamera_time_2 = QtWidgets.QPushButton(self.centralwidget)
self.opencamera_time_2.setGeometry(QtCore.QRect(720, 420, 131, 51))
self.opencamera_time_2.setToolTipDuration(1)
self.opencamera_time_2.setObjectName("opencamera_time_2")
self.label_7 = QtWidgets.QLabel(self.centralwidget)
self.label_7.setGeometry(QtCore.QRect(630, 170, 71, 31))
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.label_7.setFont(font)
self.label_7.setObjectName("label_7")
self.Openc = QtWidgets.QMessageBox(self.centralwidget)
self.Openc.setWindowTitle("消息对话框")
self.Openc.setText("相机开启")
self.Openc.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
self.Closec = QtWidgets.QMessageBox(self.centralwidget)
self.Closec.setWindowTitle("消息对话框")
self.Closec.setText("相机关闭")
self.Closec.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
self.item = QtWidgets.QInputDialog(self.centralwidget)
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.opencamera_time.setText(_translate("MainWindow", "开启定时拍摄"))
self.closecamera.setText(_translate("MainWindow", "关闭相机"))
self.delaytime.setText(_translate("MainWindow", "5"))
self.delaytime.setPlaceholderText(_translate("MainWindow", "5"))
self.label.setText(_translate("MainWindow", "设置延时拍摄间隔"))
self.label_2.setText(_translate("MainWindow", "设置图像储存地址"))
self.imagefiledir.setPlaceholderText(_translate("MainWindow", "F:/imag_collect/"))
self.imagefiledir.setText(_translate("MainWindow", "F:/imag_collect/"))
self.label_3.setText(_translate("MainWindow", "第一步"))
self.label_4.setText(_translate("MainWindow", "第三步"))
self.label_5.setText(_translate("MainWindow", "第四步"))
self.imageshow.setText(_translate("MainWindow", "相机捕获图像显示"))
self.find_camera.setText(_translate("MainWindow", "查询已连接相机"))
self.choose_camera.setText(_translate("MainWindow", "选择相机"))
self.camera_number.setPlaceholderText(_translate("MainWindow", "0"))
self.camera_number.setText(_translate("MainWindow", "0"))
self.label_6.setText(_translate("MainWindow", "单位 S"))
self.manne_camera.setText(_translate("MainWindow", "手动拍摄"))
self.opencamera_time_2.setText(_translate("MainWindow", "开启相机"))
self.label_7.setText(_translate("MainWindow", "第二步"))
def a(self):
t = threading.Thread(target=self.camera_open, name='t')
t1 = threading.Thread(target=self.time_capture, name='t1')
t.start()
t1.start()
def msg(self, Filepath):
m = QtWidgets.QFileDialog.getExistingDirectory(None, "选取文件夹", "C:/") # 起始路径
self.imagefiledir.setText(m)
def action(self):
self.closecamera.clicked.connect(self.close_c)
self.opencamera_time_2.clicked.connect(self.camera_open)
self.find_camera.clicked.connect(self.find_C)
self.opencamera_time.clicked.connect(self.time_capture)
self.manne_camera.clicked.connect(self.man_capture)
self.label_2.clicked.connect(self.msg)
def find_C(self): # 查询相机列表,并显示
cameras = list_video_devices()
self.camera_list.setText(str(cameras))
# def choose_C(self): # 选择相机序号,由用户输入序号: 0,1,2,3.。。。。
# items = ('0', '1', '2', '3', '4')
# item, ok = self.item.getItem(self,"select input dialog",'相机列表',items,0,False)
# if ok and item:
# self.camera_number.setText(str(item))
def camera_open(self): # 打开相机显示图像
self.a = 1
self.Openc.exec_() # 弹出相机开启对话框
self.cap = cv2.VideoCapture(int(self.camera_number.text()) + cv2.CAP_DSHOW)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 4032)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 3036)
while True:
ret, self.frame = self.cap.read()
if not ret:
print("无法接收到视频流")
self.cap.release()
# 显示图像 先转换格式将narry转为图像
image_data = self.frame
qimage = QtGui.QImage(image_data.data, image_data.shape[1], image_data.shape[0],
QtGui.QImage.Format_RGB888)
qimage = qimage.rgbSwapped() # 色彩通道转换
qpixmap = QtGui.QPixmap.fromImage(qimage)
pixmap = QtGui.QPixmap(qpixmap).scaled(
self.imageshow.width(), self.imageshow.height(),
aspectRatioMode=Qt.AspectRatioMode.KeepAspectRatio)
self.imageshow.setPixmap(pixmap)
cv2.waitKey(1)
if self.a == 0:
break
self.cap.release() # 释放画面
cv2.destroyAllWindows()
def close_c(self):
self.a = 0
self.Closec.exec_() # 弹出相机关闭对话框
# print('关闭相机')
self.cap.release()
cv2.destroyAllWindows()
def time_capture(self):
self.a = 1
i = 0
self.Openc.exec_() # 弹出相机开启对话框
while True:
if self.a == 1:
self.cap = cv2.VideoCapture(int(self.camera_number.text()) + cv2.CAP_DSHOW)
capture_interval = self.delaytime.text()
capture_interval = int(capture_interval)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 4032)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 3036)
# 获取当前时间
current_time = datetime.now()
# 捕获一帧
ret, frame = self.cap.read()
if not ret:
print("无法接收到视频流")
self.cap.release()
# 显示图像 先转换格式将narry转为图像
image_data = frame
qimage = QtGui.QImage(image_data.data, image_data.shape[1], image_data.shape[0],
QtGui.QImage.Format_RGB888)
qimage = qimage.rgbSwapped() # 色彩通道转换
qpixmap = QtGui.QPixmap.fromImage(qimage)
pixmap = QtGui.QPixmap(qpixmap).scaled(
self.imageshow.width(), self.imageshow.height(),
aspectRatioMode=Qt.AspectRatioMode.KeepAspectRatio)
self.imageshow.setPixmap(pixmap)
i = i + 1
# cv2.imshow('Camera Feed', frame)
# 保存图像到文件,文件名中包含当前时间
# if i % capture_interval == 0:
timestamp = current_time.strftime('%Y-%m-%d_%H-%M-%S')
filename = f'captured_{timestamp}.bmp'
cv2.imwrite(str(self.imagefiledir.text()) + '/' + filename, frame)
print(f"图像已保存: {filename}")
cv2.waitKey(capture_interval * 1000)
else:
break
self.cap.release() # 释放画面
cv2.destroyAllWindows()
def man_capture(self):
current_time = datetime.now()
# 捕获一帧
# ret, frame = self.cap.read()
timestamp = current_time.strftime('%Y-%m-%d_%H-%M-%S')
filename = f'captured_{timestamp}.bmp'
cv2.imwrite(str(self.imagefiledir.text()) + '/' + filename, self.frame)
print(f"图像已保存: {filename}")
# cv2.waitKey(1)
# self.cap.release() # 释放画面
# cv2.destroyAllWindows()
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
# import gui_rc # 导入添加的资源(根据实际情况填写文件名)
app = QApplication(sys.argv)
MainWindow = QMainWindow() # 调用
ui = Ui_MainWindow() # 调用GUI
ui.setupUi(MainWindow) # 按钮等设置
ui.action() # 按钮执行动作
MainWindow.show() # 窗口显示
sys.exit(app.exec_()) # 退出窗口
PyInstaller 打包GUI
安装 PyInstaller后,在cmd中转到代码所在的文件夹下
输入下面的代码
pyinstaller -F -w GUI.py
运行完成后可实现GUI的打包封装,封装后的.exe文件在dist文件夹下,运行时要注意:
在PyQt5库的安装路径里找到plugins\platforms文件夹,然后复制到生成的exe可执行文件旁边就能打开了。