- UI设计
- 完整源码
import sys
import time
import tkinter as tk
from tkinter import filedialog
import cv2
from PyQt5 import uic, QtGui
from PyQt5.QtCore import QTimer, QThread
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtWidgets import QApplication, QWidget, QMessageBox
class MainWidget(QWidget):
file_path = None
flag = 1
def __init__(self, parent=None):
super(MainWidget, self).__init__()
self.ui = uic.loadUi("./MyUi.ui")
self.ui.pathBtn.clicked.connect(self.set_path)
self.ui.takeBtn.clicked.connect(self.capture_image)
self.ui.startBtn.clicked.connect(self.save_video)
self.cap = cv2.VideoCapture(0) # 摄像头
self.camera_timer = QTimer()
self.camera_timer.timeout.connect(self.show_video)
self.start_video()
self.photo_flag = 0
self.ui.camera.setScaledContents(True) # 图片自适应
self.ui.imageShow.setScaledContents(True) # 图片自适应
self.ui.takeBtn.setEnabled(False)
self.ui.startBtn.setEnabled(False)
def start_video(self):
self.camera_timer.start()
# self.show_video()
def stop_video(self):
self.camera_timer.stop()
# self.cap.release()
# self.ui.camera.clear()
def set_path(self):
root = tk.Tk()
root.withdraw()
file_path = filedialog.askdirectory()
print(file_path)
if file_path == "":
return
self.file_path = file_path
self.ui.pathLabel.setText(self.file_path)
self.ui.takeBtn.setEnabled(True)
self.ui.startBtn.setEnabled(True)
def show_video(self):
flag, self.image = self.cap.read() # 从视频流中读取图片
image_show = cv2.resize(self.image, (1280, 720)) # 把读到的帧的大小重新设置为 600*360
width, height = image_show.shape[:2] # 行:宽,列:高
image_show = cv2.cvtColor(image_show, cv2.COLOR_BGR2RGB) # opencv读的通道是BGR,要转成RGB
image_show = cv2.flip(image_show, 1) # 水平翻转,因为摄像头拍的是镜像的。
# 把读取到的视频数据变成QImage形式(图片数据、高、宽、RGB颜色空间,三个通道各有2**8=256种颜色)
self.showImage = QtGui.QImage(image_show.data, height, width, QImage.Format_RGB888)
self.ui.camera.setPixmap(QPixmap.fromImage(self.showImage)) # 往显示视频的Label里显示QImage
def capture_image(self):
if self.file_path == None:
return
if self.cap.isOpened():
FName = fr"cap{time.strftime('%Y%m%d%H%M%S', time.localtime())}"
print(FName)
self.ui.imageShow.setPixmap(QtGui.QPixmap.fromImage(self.showImage))
# self.showImage.save(FName + ".jpg", "JPG", 100)
self.showImage.save(self.file_path + '/{}.jpg'.format(FName))
else:
QMessageBox.critical(self, '错误', '摄像头未打开!')
return None
def save_video(self):
if self.flag == 1:
self.ui.startBtn.setEnabled(False)
self.flag = 0
# print(self.cap.get(cv2.CAP_PROP_FPS))
self.ui.startBtn.setText("Stop Recoding")
self.stop_video()
fourcc = cv2.VideoWriter_fourcc(*"mp4v") # 保存的格式
temp = self.file_path.split("/")
real_path = ""
for i in range(0, len(temp)):
real_path += temp[i]
if i != len(temp) - 1:
real_path += "\\"
FName = fr"video{time.strftime('%Y%m%d%H%M%S', time.localtime())}"
VM = cv2.VideoWriter(real_path + "\\{}.mp4".format(FName), fourcc, 30,
(640, 480)) # 第一个参数是文件保存的名字,第二个参数是文件名称,第三个参数是帧率,第四个参数是文件的尺寸大小
self.ui.startBtn.setEnabled(True)
while True:
ret, frame = self.cap.read()
if not ret:
print("carmera,is not open")
frame = cv2.flip(frame, 1)
VM.write(frame) # 视频保存
cv2.imshow("Recording...", frame)
cv2.waitKey(1)
# if key == ord("q"):
# break
if self.flag == 1:
break
VM.release()
cv2.destroyAllWindows()
self.start_video()
else:
self.flag = 1
self.ui.startBtn.setText("Save Video")
if __name__ == '__main__':
from PyQt5 import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling) # 自适应分辨率
myapp = QApplication(sys.argv)
myWidget = MainWidget()
myWidget.ui.show()
sys.exit(myapp.exec_())
- 实现效果
首先需要选择保存路径。选择后启用按钮。点击capture按钮保存截图,点击save video开始录制视频,再次点击停止录制。
完整项目文件(含UI文件):https://download.youkuaiyun.com/download/Oceansssss/87173762