ВБ
April 16, 2021, 6:31 a.m.
Помогите переложить код QML OpenCV c PyQt5 на PySide2
Структура проекта
├── main.py
├── main.qml
└── PyCVQML
................├── cvcapture.py
................├── cvitem.py
................└──
init
.py
main.py
- import os
- import sys
- import cv2
- import numpy as np
- from PyQt5 import QtGui, QtCore, QtQuick, QtQml
- import PyCVQML
- if __name__ == '__main__':
- app = QtGui.QGuiApplication(sys.argv)
- PyCVQML.registerTypes()
- QtQml.qmlRegisterType(PyCVQML.CVCapture, "Filters", 1, 0, "GrayFilter")
- view = QtQuick.QQuickView()
- view.setTitle("PyCVQML Example")
- dir_path = os.path.dirname(os.path.realpath(__file__))
- view.setSource(QtCore.QUrl.fromLocalFile(QtCore.QDir(dir_path).absoluteFilePath("main.qml")))
- view.show()
- sys.exit(app.exec_())
main.qml
- import QtQuick 2.15
- import PyCVQML 1.0
- import Filters 1.0
- import QtQuick.Controls 2.15
- Item {
- width: 800
- height: 600
- CVItem {
- id: imageWriter
- anchors.fill: parent
- image: capture.image
- }
- CVCapture{
- id: capture
- index: 0
- filters: [max_rgb_filter, gray_filter]
- Component.onCompleted: capture.start()
- }
- }
PyCVQML/cvcapture.py
- import numpy as np
- import threading
- import cv2
- from PyQt5 import QtCore, QtGui, QtQml
- gray_color_table = [QtGui.qRgb(i, i, i) for i in range(256)]
- class CVAbstractFilter(QtCore.QObject):
- def process_image(self, src):
- dst = src
- return dst
- class CVCapture(QtCore.QObject):
- started = QtCore.pyqtSignal()
- imageReady = QtCore.pyqtSignal()
- indexChanged = QtCore.pyqtSignal()
- def __init__(self, parent=None):
- super(CVCapture, self).__init__(parent)
- self._image = QtGui.QImage()
- self._index = 0
- self.m_videoCapture = cv2.VideoCapture()
- self.m_timer = QtCore.QBasicTimer()
- self.m_filters = []
- self.m_busy = False
- @QtCore.pyqtSlot()
- @QtCore.pyqtSlot(int)
- def start(self, *args):
- if args:
- self.setIndex(args[0])
- self.m_videoCapture.release()
- self.m_videoCapture = cv2.VideoCapture(self._index)
- if self.m_videoCapture.isOpened():
- self.m_timer.start(0, self)
- self.started.emit()
- @QtCore.pyqtSlot()
- def stop(self):
- self.m_timer.stop()
- def timerEvent(self, e):
- if e.timerId() != self.m_timer.timerId():
- return
- ret, frame = self.m_videoCapture.read()
- if not ret:
- self.m_timer.stop()
- return
- if not self.m_busy:
- threading.Thread(target=self.process_image, args=(np.copy(frame),)).start()
- @QtCore.pyqtSlot(np.ndarray)
- def process_image(self, frame):
- self.m_busy = True
- for f in self.m_filters:
- frame = f.process_image(frame)
- image = CVCapture.ToQImage(frame)
- self.m_busy = False
- QtCore.QMetaObject.invokeMethod(self,
- "setImage",
- QtCore.Qt.QueuedConnection,
- QtCore.Q_ARG(QtGui.QImage, image))
- @staticmethod
- def ToQImage(im):
- if im is None:
- return QtGui.QImage()
- if im.dtype == np.uint8:
- if len(im.shape) == 2:
- qim = QtGui.QImage(im.data, im.shape[1], im.shape[0], im.strides[0], QtGui.QImage.Format_Indexed8)
- qim.setColorTable(gray_color_table)
- return qim.copy()
- elif len(im.shape) == 3:
- if im.shape[2] == 3:
- w, h, _ = im.shape
- rgb_image = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
- flip_image = cv2.flip(rgb_image, 1)
- qim = QtGui.QImage(flip_image.data, h, w, QtGui.QImage.Format_RGB888)
- return qim.copy()
- return QtGui.QImage()
- def image(self):
- return self._image
- @QtCore.pyqtSlot(QtGui.QImage)
- def setImage(self, image):
- if self._image == image:
- return
- self._image = image
- self.imageReady.emit()
- def index(self):
- return self._index
- def setIndex(self, index):
- if self._index == index:
- return
- self._index = index
- self.indexChanged.emit()
- @QtCore.pyqtProperty(QtQml.QQmlListProperty)
- def filters(self):
- return QtQml.QQmlListProperty(CVAbstractFilter, self, self.m_filters)
- image = QtCore.pyqtProperty(QtGui.QImage, fget=image, notify=imageReady)
- index = QtCore.pyqtProperty(int, fget=index, fset=setIndex, notify=indexChanged)
PyCVQML/cvitem.py
- from PyQt5 import QtCore, QtGui, QtQuick
- class CVItem(QtQuick.QQuickPaintedItem):
- imageChanged = QtCore.pyqtSignal()
- def __init__(self, parent=None):
- super(CVItem, self).__init__(parent)
- ## self.setRenderTarget(QtQuick.QQuickPaintedItem.FramebufferObject)
- self.m_image = QtGui.QImage()
- def paint(self, painter):
- if self.m_image.isNull():
- return
- image = self.m_image.scaled(self.size().toSize())
- painter.drawImage(QtCore.QPoint(), image)
- def image(self):
- return self.m_image
- def setImage(self, image):
- if self.m_image == image:
- return
- self.m_image = image
- self.imageChanged.emit()
- self.update()
- image = QtCore.pyqtProperty(QtGui.QImage, fget=image, fset=setImage, notify=imageChanged)
PyCVQML/ init .py
- from PyQt5 import QtQml
- from .cvcapture import CVCapture, CVAbstractFilter
- from .cvitem import CVItem
- def registerTypes(uri="PyCVQML"):
- QtQml.qmlRegisterType(CVCapture, uri, 1, 0, "CVCapture")
- QtQml.qmlRegisterType(CVItem, uri, 1, 0, "CVItem")
1
43
Do you like it? Share on social networks!
- Last comments
- AKApril 1, 2025, 11:41 a.m.Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
- VPMarch 9, 2025, 4:14 p.m.Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
- ИМNov. 22, 2024, 9:51 p.m.Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
- Now discuss on the forum
- fFeb. 15, 2025, 1:46 p.m.Подскажите, пожалуйста! Как данный класс можно дополнить, чтобы созданные объекты можно было перемещать мышкой по сцене?
- Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
- Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
- Спасибо большое за помощь и простите за то что отнял время своей невнимательностью.