疫情期间的闭门造车工程,借此机会初入图像领域
一直打算边学图像,边做一个图像学习的软件,但是越来越发现没有必要,因为感觉程序直接裸跑验证就行了,没有必要封装成一个软件,于是删减删减删减,精简功能后达到下图效果,源码下图有,自己配好环境可以运行,工程文件打包后期上传
功能简述:
1.打开相机,显示相机图像
2.关闭相机显示
3.保存录像
4.截屏当前视频,保存图片
5.识别视频中的人脸位置画上方框
环境陈述(默认开发环境已配好):
开发系统:Linux
运行系统:Linux,Windows10
开发软件:Python3,Qt designer ,pycharm
打包工具:pyinstaller
打包环境:win10
程序工程文件夹:
打包后的运行环境:
其中image1和output是运行产生的,其他为依赖文件
工程建立,等等流程同https://blog.csdn.net/qq_36071362/article/details/104170846,不做具体记录,只记录注意事项
1.依赖文件打包:打包后找齐依赖文件和exe放在同一个目录下,可以打包时一起加入(修改spec文件),但是一般不这么干, 试了试没成功
2.依赖文件:需要人脸识别器,pic1是相机初始图片,。。。dll为OpenCV保存视频必须的,位置在opencv的安装路径中,否则 AVI视频不能正常保存
3.录像计时不准,随便诌了一个,,懒得找了
4.打包指令:pyinstaller --hidden-import=PyQt5 -w -F cam_minisoft_ser.py -p cam_minisoft_ser.py
下面贴出服务函数源码
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMessageBox
from cam_minisoft import Ui_Form
from PyQt5.QtWidgets import QApplication, QMainWindow, QGridLayout
from PyQt5.QtCore import QTimer, QCoreApplication
import numpy as np
from PyQt5.QtGui import QPixmap
import sys
import cv2
import qimage2ndarray
import time
cap = cv2.VideoCapture(0)
g_img = cv2.imread('pic1.PNG')
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
class Pyqt5_cam(QtWidgets.QWidget, Ui_Form): # 创建画板,继承自FigureCanvas类
def __init__(self):
super(Pyqt5_cam, self).__init__()
self.setupUi(self)
self.init()
self.setWindowTitle("MLW_Cam")
self.Timer = QTimer()
self.Timer.timeout.connect(self.DispImg)
# self.Timer.start(1)
self.s_flag = 0
self.count_time = 0
self.start_time = 0
self.all_time = 0
# 显示"打开摄像头"前的图像
global g_img
g_img = cv2.cvtColor(g_img, cv2.COLOR_BGR2RGB)
qimg = qimage2ndarray.array2qimage(g_img)
self.DispLb.setPixmap(QPixmap(qimg))
self.DispLb.show()
# 把按钮等控件和函数对应起来
def init(self):
# 串口检测按钮
self.button1.clicked.connect(self.start_cam)
self.button2.clicked.connect(self.close_cam)
self.button3.clicked.connect(self.save_video)
self.button4.clicked.connect(self.stop_save_video)
self.button5.clicked.connect(self.save_pic)
def start_cam(self):
# 重新打开摄像头
cap.open(0)
self.Timer.start(1)
def close_cam(self):
# 关闭摄像头
cap.release()
self.count_time = 0
self.Timer.stop()
self.all_time = 0
def save_video(self):
if self.count_time > 0: # 相机打开后才能录像
self.s_flag = 1
self.state_label.setText(" 正在录像:")
self.count_time = 0
def stop_save_video(self):
if self.s_flag == 1:
self.s_flag = 0
self.state_label.setText(" 录像停止")
def save_pic(self):
sucess, g_img = cap.read()
cv2.imwrite("image1.jpg", g_img)
def DispImg(self):
global g_img
self.count_time += 1
if self.count_time >= 6000:
self.count_time = 0
sucess, g_img = cap.read()
# success, g_img = self.camera.read()
# cv2.imshow('img', g_img)
gray = cv2.cvtColor(g_img, cv2.COLOR_BGR2GRAY)
# 绘制人脸周围的矩形
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5)
for (x, y, w, h) in faces:
g_img = cv2.rectangle(g_img, (x, y), (x+w, y+h), (255, 0, 0), 2)
# 显示计时时间
if self.s_flag == 1:
out.write(g_img)
if self.count_time >= 23:
self.all_time += 1
self.count_time = 0
self.state_label_2.setText(str(self.all_time))
g_img = cv2.cvtColor(g_img, cv2.COLOR_BGR2RGB)
qimg = qimage2ndarray.array2qimage(g_img)
self.DispLb.setPixmap(QPixmap(qimg))
self.DispLb.show()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv) # 实例化一个应用对象
myshow = Pyqt5_cam()
myshow.show() # 让控件在桌面上显示出来。控件在内存里创建,之后才能在显示器上显示出来。
sys.exit(app.exec_()) # 程序一直循环运行到主窗口被关闭
下面贴出ui文件转换完的py文件
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'cam_minisoft.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(983, 892)
self.button3 = QtWidgets.QPushButton(Form)
self.button3.setGeometry(QtCore.QRect(370, 840, 81, 33))
self.button3.setObjectName("button3")
self.button1 = QtWidgets.QPushButton(Form)
self.button1.setGeometry(QtCore.QRect(40, 840, 81, 33))
self.button1.setObjectName("button1")
self.button2 = QtWidgets.QPushButton(Form)
self.button2.setGeometry(QtCore.QRect(140, 840, 81, 33))
self.button2.setObjectName("button2")
self.button5 = QtWidgets.QPushButton(Form)
self.button5.setGeometry(QtCore.QRect(840, 840, 111, 33))
self.button5.setObjectName("button5")
self.DispLb = QtWidgets.QLabel(Form)
self.DispLb.setGeometry(QtCore.QRect(30, 30, 921, 791))
self.DispLb.setText("")
self.DispLb.setScaledContents(True)
self.DispLb.setObjectName("DispLb")
self.button4 = QtWidgets.QPushButton(Form)
self.button4.setGeometry(QtCore.QRect(470, 840, 81, 33))
self.button4.setObjectName("button4")
self.state_label = QtWidgets.QLabel(Form)
self.state_label.setGeometry(QtCore.QRect(560, 839, 71, 31))
self.state_label.setObjectName("state_label")
self.state_label_2 = QtWidgets.QLabel(Form)
self.state_label_2.setGeometry(QtCore.QRect(630, 840, 31, 31))
self.state_label_2.setText("")
self.state_label_2.setObjectName("state_label_2")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.button3.setText(_translate("Form", "开始录像"))
self.button1.setText(_translate("Form", "打开相机"))
self.button2.setText(_translate("Form", "关闭相机"))
self.button5.setText(_translate("Form", "保存图片"))
self.button4.setText(_translate("Form", "停止录像"))
self.state_label.setText(_translate("Form", "未在录像"))