影片人臉偵測
本範例使用 Pyside 的 OpenGLWidget進行影片播放。
1. 首先使用cv2.VideoCapture()開啟影片,然後一幅一幅讀入,進行處理
a. 原始影格為 frame, 但size過大, 處理人臉偵測費時過久, 所以縮小成20%的frame_defect
b. 畫框線時, 需於frame乖上rate,放大標示框線
2. 將處理好的影片,傳送到OpenGLWidget進行update播放
MainWindow.py
import sys from PyQt5.QtWidgets import QMainWindow, QApplication, QVBoxLayout from MahalGl import MahalGl from VideoThread import VideoThread from ui.ui_mainwindow import Ui_MainWindow class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self, parent=None): super().__init__(parent) self.setupUi(self) layout=QVBoxLayout(self.frame) self.mahalGl=MahalGl() layout.addWidget(self.mahalGl) self.thread=VideoThread() self.thread.callback.connect(self.refresh) self.thread.start() def refresh(self, img): self.mahalGl.showImg=img self.mahalGl.update() app=QApplication(sys.argv) frame=MainWindow() frame.show() app.exec()
VideoThread.py
import cv2 import dlib from PyQt5.QtCore import QThread, pyqtSignal from MahalCv import MahalCv as cv class VideoThread(QThread): callback=pyqtSignal(object) def __init__(self, parent=None): super().__init__(parent) self.runFlag=True def __del__(self): self.runFlag=False self.wait() def run(self): video=cv2.VideoCapture("movie.mkv") #指定影片從指定的秒數開始播放(900秒) video.set(cv2.CAP_PROP_POS_MSEC, 900000) #frame_width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH)) #frame_height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)) detector = dlib.get_frontal_face_detector() while video.isOpened() and self.runFlag: rate=5 ret, frame = video.read() frame_detect = cv.resize(frame, scale=0.2) face = detector(frame_detect, 1) for i, d in enumerate(face): x1 = int(d.left() * rate) y1 = int(d.top() * rate) x2 = int(d.right() * rate) y2 = int(d.bottom() * rate) cv.rect(frame, x1, y1, x2, y2, color=(0,255,0), width=2) img=cv.cv2qimage(frame) self.callback.emit(img) QThread.msleep(1) video.release()
MahalGl.py
from PyQt5.QtCore import QPoint from PyQt5.QtGui import QPainter, QImage from PyQt5.QtWidgets import QOpenGLWidget class MahalGl(QOpenGLWidget): def __init__(self,parent = None): super().__init__(parent) self.showImg=None def paintGL(self): print(self.width()) if self.showImg is not None: paint = QPainter() paint.begin(self) #隨OpenGLWidget的大小縮放圖片 self.showImg=self.showImg.smoothScaled(self.width(), self.height()) paint.drawImage(QPoint(0,0),self.showImg) paint.end()