ВБ
Владимир Борисов15 квітня 2021 р. 20:31
Помогите переложить код 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")
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.Вам це подобається? Поділіться в соціальних мережах!
AD
- Akiv Doros
- 12 листопада 2024 р. 02:58
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:50бали,
- Рейтинг балів-4
m
- molni99
- 26 жовтня 2024 р. 12:37
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:80бали,
- Рейтинг балів4
m
- molni99
- 26 жовтня 2024 р. 12:29
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:20бали,
- Рейтинг балів-10
Останні коментарі
ИМ
Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Игорь Максимов22 листопада 2024 р. 23:51
Evgenii Legotckoi01 листопада 2024 р. 01:37
Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
Игорь Максимов05 жовтня 2024 р. 18:51
QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Тепер обговоріть на форумі
Evgenii Legotckoi25 червня 2024 р. 02:11
t
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
tonypeachey115 листопада 2024 р. 18:04
NSProject04 червня 2022 р. 14:49
IscanderChe01 листопада 2024 р. 02:43
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…