Динамическое изменение размера видео в PyQt - PullRequest
0 голосов
/ 03 августа 2020

Я бьюсь головой о стену, пытаясь понять, как изменить размер и переставить приложение камеры, которое я создаю на Raspberry Pi. Я хочу иметь возможность изменять размер окна, нажимая на видео, из полноэкранного приложения в меньшую версию, которая будет отображаться в углу моего сенсорного экрана.

https://github.com/eighty2fifty1/multicam

Small Screen

Полноэкранный

Я использую OpenCV для запуска самой камеры. Хотя цель приложения состоит в том, чтобы запускать 4 камеры и переключаться между ними, все это происходит на внешнем оборудовании, поэтому просто думайте об этом как о отображении одной веб-камеры USB. Я не полностью настроен на использование OpenCV для этого, но до сих пор он работал.

Я также, кажется, получаю ошибки сегментации на моем RPi 4, когда я пытаюсь отрегулировать размер, минимизировать или максимизировать окно. Не уверен, связано ли это, но я пробовал использовать две новые SD-карты, надеясь исключить аппаратную проблему.

Что я пробовал:

  • Программно переставляем окно. Не отображает видео, а также вызывает ошибку сегментации.

  • Создание подкласса MyWindowClass в BigWindowClass и SmallWindowClass, затем отправка отдельных файлов .ui в их соответствующие классы, затем использование .show ( ) и .hide (), чтобы определить, какой из них я хочу отобразить. Это покажет видео в большом окне, но не в маленьком.

Для ясности я пропустил несколько своих функций, но полный исходный код находится в ссылке на github выше.

class Thread(QThread):
    global file, big, small
    changePixmap = pyqtSignal(QImage)

    def run(self):
        cap = cv2.VideoCapture(0)
        while running:
            ret, frame = cap.read()
            if ret:
                # not sure if the queue was necessary to prevent memory or processor problems
                if q.qsize() < 10:
                    q.put(frame)
                else:
                    print(q.qsize())

                if not q.empty():
                    f = q.get()
                    rgbImage = cv2.cvtColor(f, cv2.COLOR_BGR2RGB)
                    h, w, ch = rgbImage.shape
                    bytesPerLine = ch * w
                    convertToQtFormat = QImage(rgbImage.data, w, h, bytesPerLine, QImage.Format_RGB888)
                    if file == big:
                        p = convertToQtFormat.scaled(640, 480, Qt.KeepAspectRatio)
                    elif file == small:
                        p = convertToQtFormat.scaled(200, 150, Qt.KeepAspectRatio)

                    else:
                        pass
                    self.changePixmap.emit(p)

        if self.isFinished():
            print("thread killed")


class MyWindowClass(QMainWindow, form_class):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.sel = Selector()
        self.press = 0
        self.rel = 0

        self.videoLbl = ClickableLabel(self.videoLbl)
        self.setWindowTitle('Camera')

        self.connectSignals()
        self.th = Thread(self)
        self.th.changePixmap.connect(self.setImage)
        self.th.start()
        self.show()

    @pyqtSlot(QImage)
    def setImage(self, image):
        pixmap = QPixmap.fromImage(image)
        self.videoLbl.setPixmap(pixmap)

 # this will eventually be the function to change views
    def _resize(self):
        print("resize clicked")

    # signal connections
    def connectSignals(self):
        self.cam1.clicked.connect(lambda: self.sel.selectCamera(1))
        self.cam2.clicked.connect(lambda: self.sel.selectCamera(2))
        self.cam3.clicked.connect(lambda: self.sel.selectCamera(3))
        self.cam4.clicked.connect(lambda: self.sel.selectCamera(4))

        self.buttonGroup.setId(self.cam1, 1)
        self.buttonGroup.setId(self.cam2, 2)
        self.buttonGroup.setId(self.cam3, 3)
        self.buttonGroup.setId(self.cam4, 4)
        '''
        self.resizeButton.clicked.connect(resizeWindow)
        self.posCheck.clicked.connect(posit)
        '''
        self.pairButton.pressed.connect(self.prPress)
        self.pairButton.released.connect(self.prRel)

        self.sel.camSelected.connect(self.selected)
        self.videoLbl.clicked.connect(self._resize)


app = QtWidgets.QApplication(sys.argv)
window = MyWindowClass(None)
window.show()
running = True

app.exec_()

1 Ответ

0 голосов
/ 04 августа 2020

Итак, я нашел решение самостоятельно. Возможно, это не самый элегантный или эффективный вариант, но он работает. Я получил большую подсказку от Qt вылетает, когда изображение из OpenCV слишком велико , что мне нужно сначала скопировать мой QImage.

convertToQtFormat = QImage(rgbImage.data, w, h, bytesPerLine, QImage.Format_RGB888)
i = convertToQtFormat.copy()
self.changePixmap.emit(i)

Я пересмотрел попытку подкласса моего главного окна и использования 2 отдельных файла .ui, и после еще нескольких настроек программа работает должным образом.

https://github.com/eighty2fifty1/multicam/blob/master/multicam4.py

...