需要自行安装opencv,复制即用
其余废话少说,上代码
######################################################
# PyCamera.py #
# Copyright (c) 2021 By LiuHui. All Rights Reserved. #
# #
# Email: specterlh@163.com #
######################################################from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import QCoreApplication, QThread, QObject, pyqtSignal
import cv2
import sys
import window
import math
import numpy as np
import time
import os'''PyQt5窗口页面'''
class Ui_MainWindow(QtWidgets.QWidget):'''窗口初始化'''def __init__(self, window):super().__init__(window)self.MainWindow = window #定义窗口控件self.threads = [] #定义多线程数组self.caps = [] #定义摄像头数组self.labels = [] #定义摄像头显示位置self.timers = [] #定义定时器, 用于控制显示帧率self.setupUi() #定义窗口页面布局'''设置页面布局''' def setupUi(self): self.MainWindow.setObjectName("MainWindow") #窗口控件名称self.MainWindow.resize(800, 600) #窗口控件尺寸self.centralwidget = QtWidgets.QWidget(self.MainWindow) #设置底层控件self.centralwidget.setObjectName("centralwidget") #设置底层控件名称self.gridLayout = QtWidgets.QGridLayout(self.centralwidget) #设置网格布局控件self.gridLayout.setObjectName("gridLayout") #设置网格控件名称self.MainWindow.setCentralWidget(self.centralwidget) #绑定窗口底层控件self.statusbar = QtWidgets.QStatusBar(self.MainWindow) #添加状态栏self.statusbar.setObjectName("statusbar")self.MainWindow.setStatusBar(self.statusbar)self.action = QtWidgets.QAction(self.MainWindow) #添加菜单动作self.action.setObjectName("action")self.action_2 = QtWidgets.QAction(self.MainWindow) #添加菜单动作self.action_2.setObjectName("action_2")self.menubar = QtWidgets.QMenuBar(self.MainWindow) #添加菜单栏self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))self.menubar.setObjectName("menubar")self.menu = QtWidgets.QMenu(self.menubar) #添加菜单事件self.menu.setObjectName("menu")self.menu.addAction(self.action)self.menu.addAction(self.action_2)self.menubar.addAction(self.menu.menuAction()) #菜单栏添加事件self.MainWindow.setMenuBar(self.menubar)self.retranslateUi() #设置控件文本QtCore.QMetaObject.connectSlotsByName(self.MainWindow)'''设置控件显示文本'''def retranslateUi(self):_translate = QtCore.QCoreApplication.translateself.MainWindow.setWindowTitle(_translate("MainWindow", "智慧视频"))self.menu.setTitle(_translate("MainWindow", "设置"))self.action.setText(_translate("MainWindow", "摄像头"))self.action.triggered.connect(self.refreshCamera)self.action_2.setText(_translate("MainWindow", "关闭"))self.action_2.triggered.connect(self.close_Window)'''扫码已有摄像头,返回编号'''def GetUsbCameraIO(self):ids = []for i in range(10):camera = cv2.VideoCapture(i)if camera.isOpened():ids.append(i)return ids'''关闭窗口'''def close_Window(self):for thread in self.threads:thread.quit()self.MainWindow.close()'''刷新摄像头布局'''def refreshCamera(self):#停止现有的多线程for thread in self.threads:thread.quit()self.ids = self.GetUsbCameraIO() #获取当前所有可连接摄像头的idids = np.array(self.ids) #将数组转换为矩阵n = len(ids) #获取矩阵长度cols = math.ceil(math.sqrt(n)) #取矩阵开方下的最接近整数,向下取整rows = math.floor(math.sqrt(n)) #取矩阵开方下的最接近整数,向上取整if cols*rows<n: #如果数量不够,增加一行rows = rows+1arr = np.empty(cols*rows) #创建一个空矩阵arr[:n] = ids #空矩阵的前面为id矩阵arr[n:] = -1 #空矩阵后面为-1arr = arr.reshape((rows,cols)) #将矩阵转换为rows*cols的矩阵self.arr = arr#循环创建布局及控件for i in range(rows):for j in range(cols):label = QtWidgets.QLabel(self.centralwidget) #创建label控件self.gridLayout.addWidget(label, i, j, 1, 1) #设置label布局thread_i = QThread() #创建多个线程timer = QtCore.QTimer() #创建定时器cap = myCamera(label, int(arr[i][j]), timer) #定义一个新的摄像机cap.signal.connect(self.flush) #摄像机可以触发状态改变cap.moveToThread(thread_i) #将摄像机绑定到线程timer.moveToThread(thread_i) #将定时器绑定到线程thread_i.started.connect(cap.started) #绑定线程起始事件thread_i.finished.connect(cap.finished) #绑定线程终止事件thread_i.start() #线程启动self.threads.append(thread_i) #记录线程self.caps.append(cap) #记录摄像机self.labels.append(label) #记录文本控件self.timers.append(timer) #记录计时器'''设置摄像头文本显示''' def flush(self, label, txt):label.setText(txt)'''定义摄像机类'''
class myCamera(QObject):signal = pyqtSignal(QtWidgets.QLabel, str) #摄像机类返回信号'''初始化摄像机'''def __init__(self, label, capIndex, timer):super(myCamera, self).__init__() self.label = labelself.timer_camera = timer #帧数定时器self.capIndex = capIndex #相机编号'''设置显示图片''' def show(self):pos = self.label.geometry() #获取label大小flag, image = self.cap.read() #读取摄像机图片#图像上写入当前时间timestr = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) #获取当前时间,格式yyyy-mm-dd HH:MM:sstimestr = timestr + " Camera"+str(self.capIndex)cv2.putText(image, timestr, (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255,255,255), 1)'''显示图片'''show = cv2.resize(image, (pos.width(), pos.height())) #调整摄像机图片尺寸show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB) #转换颜色到rgbshowImage = QtGui.QImage(show.data,show.shape[1],show.shape[0],show.shape[1]*3,QtGui.QImage.Format_RGB888) #转换图片格式showImage = QtGui.QPixmap.fromImage(showImage) #转换图片格式self.label.setPixmap(showImage) #设置图片显示'''摄像头启动事件''' def started(self):self.timer_camera.timeout.connect(self.show) #设置计时器绑定self.signal.emit(self.label, "摄像头连接中,请稍候") #设置文本显示self.cap = cv2.VideoCapture(self.capIndex)print("start:Camera"+str(self.capIndex))self.timer_camera.start(30)'''摄像头停止事件''' def finished(self):self.timer_camera.stop() #关闭定时器self.cap.release() #释放视频流self.label.setText("摄像头已断开")if __name__=='__main__':app = QApplication(sys.argv)mainWindow = QMainWindow()ui = Ui_MainWindow(mainWindow)ui.setupUi()mainWindow.show()sys.exit(app.exec_())
程序使用效果