Как запустить и остановить трансляцию с камеры с помощью OpenCV и pyqt5?

#python #opencv #user-interface #pyqt5

Вопрос:

Мне нужно создать приложение, которое отображает видеопоток с камеры, и я хочу иметь возможность запускать и останавливать канал, когда захочу. Вот что у меня есть до сих пор: я запускаю новое ядро, запускаю приведенный ниже сценарий, и все работает так, как задумано. Теперь я закрываю приложение кнопкой закрытия Windows, снова запускаю скрипт, я могу запустить канал, однако, когда я пытаюсь остановить канал, он выключает ядро. Я понятия не имею, почему это происходит.

РЕДАКТИРОВАТЬ: Я только что узнал, что запуск и остановка несколько раз также приводят к сбою ядра.

 # -*- coding: utf-8 -*- import sys from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import * import cv2  class MainWindow(QWidget):  def __init__(self):  super().__init__()    self.resize(300,300)  self.globalLayout = QVBoxLayout(self)   self.feedLabel = QLabel(self)  self.feedLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)  self.feedLabel.setStyleSheet("background-color:pink")      self.start_btn=QPushButton("Start feed", self)  self.cancel_btn = QPushButton("Cancel", self)  self.saveImg_btn=QPushButton("Save image", self)    self.select_camera=QComboBox(self)  self.select_camera.addItems(["0","1"])    buttons_widget=QWidget(self)  buttons_layout=QHBoxLayout(buttons_widget)  buttons_layout.addWidget(self.start_btn)  buttons_layout.addWidget(self.cancel_btn)  buttons_layout.addWidget(self.saveImg_btn)  buttons_layout.addWidget(self.select_camera)    self.globalLayout.addWidget(self.feedLabel)  self.globalLayout.addWidget(buttons_widget)    self.setLayout(self.globalLayout)    self.start_btn.clicked.connect(self.start_feed)  self.cancel_btn.clicked.connect(self.stop_feed)    #create a thread   self.thread = QThread()  #create a worker  self.worker = Worker()  #move worker to thread  self.worker.moveToThread(self.thread)  #run method  self.thread.started.connect(self.worker.run)     self.worker.imageUpdate.connect(self.set_new_img)    self.worker.finished.connect(self.worker_done)  self.thread.finished.connect(self.thread_done)      def start_feed(self):  self.worker.camera=cv2.VideoCapture(int(self.select_camera.currentText()), cv2.CAP_DSHOW)  self.worker.running=True    #Start the thread  self.thread.start()    def stop_feed(self):  self.worker.running = False  print("feed was asked to stop")    def worker_done(self):  print("worker finished")  self.worker.camera.release()  self.thread.quit()    def thread_done(self):  print("thread finished")    def set_new_img(self,Image):  print("it received the signal")  print(Image)  self.feedLabel.setPixmap(QPixmap.fromImage(Image))     class Worker(QObject):  finished = pyqtSignal() #signals to communicate with main  imageUpdate = pyqtSignal(QImage) #should be class attributes    def __init__(self):  super().__init__()  self.camera=None  self.running=None    def run(self):    while self.running:  ret, frame = self.camera.read()  if ret:  Image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  FlippedImage = cv2.flip(Image, 1)  ConvertToQtFormat = QImage(FlippedImage.data, FlippedImage.shape[1], FlippedImage.shape[0], QImage.Format_RGB888)  Pic = ConvertToQtFormat.scaled(640, 480, Qt.KeepAspectRatio)  print("it got the pic")  self.imageUpdate.emit(Pic)    print("nfinished signal emited")   self.finished.emit()       if __name__ == "__main__":  App = QApplication(sys.argv)  Root = MainWindow()  Root.show()  sys.exit(App.exec())  

Комментарии:

1. Что вы подразумеваете под «ядром»?

2. Я не уверен, как это описать, так как я точно не знаю технических терминов, но вот что происходит: приложение зависает, оно закрывается, и я получаю «Перезапуск ядра» в консоли. Я проверяю это на Spyder. Это помогает?

3. Попробуйте запустить программу из терминала или командной строки.

4. Это даже не позволяет мне один раз остановиться из cmd. Он просто закрывает окно таким образом всякий раз, когда я нажимаю кнопку «Стоп».

5. Я не могу проверить ваш код, так как у меня сейчас нет подключенной камеры. Он падает бесшумно или вы получаете что-нибудь до этого?