ВБ
Владимир БорисовApril 15, 2021, 8:31 p.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")
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.Do you like it? Share on social networks!
B
- Bogdannn
- March 28, 2024, 2:15 a.m.
C++ - Test 001. The first program and data types
- Result:46points,
- Rating points-6
Last comments
Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Qt WinAPI - Lesson 007. Working with ICMP Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Анатолий КононенкоFeb. 5, 2024, 9:50 a.m.
EVADec. 25, 2023, 6:30 p.m.
Boost - static linking in CMake project under Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
Qt/C++ - Lesson 056. Connecting the Boost library in Qt for MinGW and MSVC compilers Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Now discuss on the forum
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
Павел ДорофеевApril 14, 2024, 9:35 a.m.
Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…
Как получить в массив значения из связанной модели? Спасибо, разобрался:))
AC
QML Обнулить значения SpinBox Доброго времени суток, не могу разобраться с обнулением значение SpinBox находящего в делегате. import QtQuickimport QtQuick.ControlsWindow { width: 640 height: 480 visible: tr…
Alexandru CodreanuJan. 19, 2024, 7:57 p.m.