无法使用pyqt线程为cv2.VideoCapture()获取视频路径输入

2024-04-19 23:11:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望使用从QFileDialog()中选择的文件来发出帧,而不是每次都写入cv2捕获的路径或从命令行获取参数。此外,我还将使用另一个按钮在GUI上显示的视频文件列表中切换。因此,我还希望这些文件路径被进一步馈送到循环中。 还有一种方法可以在显示另一个文件之前清除pixmap吗

from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, QWidget, QMessageBox , QLabel
from PyQt5.QtGui import QIcon, QImage, QPixmap, QColor, QRegExpValidator
from PyQt5.QtCore import QTimer, QRegExp, pyqtSignal, pyqtSlot, Qt, QThread

import os
import sys
import numpy as np
import pathlib
import cv2
import time
from PIL import Image


class VideoThread(QThread):
    change_pixmap_signal = pyqtSignal(np.ndarray)

    def run(self):
        # capture from path file
        cap = cv2.VideoCapture('videos/video.mp4')
        while True:
            ret, cv_img = cap.read()
            if ret:
                self.change_pixmap_signal.emit(cv_img)


class VideoWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = UIVideo()
        self.ui.setupUi(self)
        self.setWindowIcon(QtGui.QIcon('icon.png'))
        self.ui.trainNewInput.clicked.connect(self.pick_new)
        self.ui.detect.clicked.connect(self.file_detect)
        self.ui.video_index=0

    def file_detect(self):
        # create the video capture thread
        self.thread = VideoThread()
        # connect its signal to the update_image slot
        self.thread.change_pixmap_signal.connect(self.update_image)
        # start the thread
        self.thread.start()


    @pyqtSlot(np.ndarray)
    def update_image(self, cv_img):
        """Updates the image_label with a new opencv image"""
        qt_img = self.convert_cv_qt(cv_img)
        self.ui.photo_img.setPixmap(qt_img)
    

    def convert_cv_qt(self, cv_img):
        """Convert from an opencv image to QPixmap"""
        rgb_image = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
        h, w, ch = rgb_image.shape
        bytes_per_line = ch * w
        convert_to_Qt_format = QtGui.QImage(rgb_image.data, w, h, bytes_per_line, QtGui.QImage.Format_RGB888)
        p = convert_to_Qt_format.scaled(640, 640, Qt.KeepAspectRatio)
        return QPixmap.fromImage(p)


    def pick_new(self):
        self.ui.dialog = QtWidgets.QFileDialog()
        self.ui.folder_path = self.ui.dialog.getExistingDirectory(None, "Select Folder")
        print(self.ui.folder_path)
        self.ui.file_name = []
        for root, dirs, files in os.walk(self.ui.folder_path):
            for file in files:
                if file.endswith('.mp4') or file.endswith('.avi'):
                    self.ui.file_name.append(file)

        print(self.ui.file_name)
        video_path = "videos/"+ self.ui.file_name[self.ui.video_index]
        

Tags: pathfromimageimportselfuiimgdef