ВБ
16 апреля 2021 г. 6:31

Помогите переложить код QML OpenCV c PyQt5 на PySide2

Структура проекта
├── main.py
├── main.qml
└── PyCVQML
................├── cvcapture.py
................├── cvitem.py
................└── init .py


main.py

  1. import os
  2. import sys
  3. import cv2
  4. import numpy as np
  5. from PyQt5 import QtGui, QtCore, QtQuick, QtQml
  6. import PyCVQML
  7.  
  8.  
  9. if __name__ == '__main__':
  10.  
  11. app = QtGui.QGuiApplication(sys.argv)
  12.  
  13. PyCVQML.registerTypes()
  14. QtQml.qmlRegisterType(PyCVQML.CVCapture, "Filters", 1, 0, "GrayFilter")
  15.  
  16. view = QtQuick.QQuickView()
  17. view.setTitle("PyCVQML Example")
  18. dir_path = os.path.dirname(os.path.realpath(__file__))
  19. view.setSource(QtCore.QUrl.fromLocalFile(QtCore.QDir(dir_path).absoluteFilePath("main.qml")))
  20. view.show()
  21. sys.exit(app.exec_())

main.qml

  1. import QtQuick 2.15
  2. import PyCVQML 1.0
  3. import Filters 1.0
  4. import QtQuick.Controls 2.15
  5.  
  6. Item {
  7. width: 800
  8. height: 600
  9.  
  10. CVItem {
  11. id: imageWriter
  12. anchors.fill: parent
  13. image: capture.image
  14. }
  15.  
  16.  
  17. CVCapture{
  18. id: capture
  19. index: 0
  20. filters: [max_rgb_filter, gray_filter]
  21. Component.onCompleted: capture.start()
  22. }
  23. }

PyCVQML/cvcapture.py

  1. import numpy as np
  2. import threading
  3.  
  4. import cv2
  5.  
  6. from PyQt5 import QtCore, QtGui, QtQml
  7.  
  8. gray_color_table = [QtGui.qRgb(i, i, i) for i in range(256)]
  9.  
  10.  
  11. class CVAbstractFilter(QtCore.QObject):
  12. def process_image(self, src):
  13. dst = src
  14. return dst
  15.  
  16.  
  17. class CVCapture(QtCore.QObject):
  18. started = QtCore.pyqtSignal()
  19. imageReady = QtCore.pyqtSignal()
  20. indexChanged = QtCore.pyqtSignal()
  21.  
  22. def __init__(self, parent=None):
  23. super(CVCapture, self).__init__(parent)
  24. self._image = QtGui.QImage()
  25. self._index = 0
  26.  
  27. self.m_videoCapture = cv2.VideoCapture()
  28. self.m_timer = QtCore.QBasicTimer()
  29. self.m_filters = []
  30. self.m_busy = False
  31.  
  32. @QtCore.pyqtSlot()
  33. @QtCore.pyqtSlot(int)
  34. def start(self, *args):
  35. if args:
  36. self.setIndex(args[0])
  37. self.m_videoCapture.release()
  38. self.m_videoCapture = cv2.VideoCapture(self._index)
  39. if self.m_videoCapture.isOpened():
  40. self.m_timer.start(0, self)
  41. self.started.emit()
  42.  
  43. @QtCore.pyqtSlot()
  44. def stop(self):
  45. self.m_timer.stop()
  46.  
  47. def timerEvent(self, e):
  48. if e.timerId() != self.m_timer.timerId():
  49. return
  50. ret, frame = self.m_videoCapture.read()
  51. if not ret:
  52. self.m_timer.stop()
  53. return
  54. if not self.m_busy:
  55. threading.Thread(target=self.process_image, args=(np.copy(frame),)).start()
  56.  
  57. @QtCore.pyqtSlot(np.ndarray)
  58. def process_image(self, frame):
  59. self.m_busy = True
  60. for f in self.m_filters:
  61. frame = f.process_image(frame)
  62. image = CVCapture.ToQImage(frame)
  63. self.m_busy = False
  64. QtCore.QMetaObject.invokeMethod(self,
  65. "setImage",
  66. QtCore.Qt.QueuedConnection,
  67. QtCore.Q_ARG(QtGui.QImage, image))
  68.  
  69. @staticmethod
  70. def ToQImage(im):
  71. if im is None:
  72. return QtGui.QImage()
  73. if im.dtype == np.uint8:
  74. if len(im.shape) == 2:
  75. qim = QtGui.QImage(im.data, im.shape[1], im.shape[0], im.strides[0], QtGui.QImage.Format_Indexed8)
  76. qim.setColorTable(gray_color_table)
  77. return qim.copy()
  78.  
  79. elif len(im.shape) == 3:
  80. if im.shape[2] == 3:
  81. w, h, _ = im.shape
  82. rgb_image = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
  83. flip_image = cv2.flip(rgb_image, 1)
  84. qim = QtGui.QImage(flip_image.data, h, w, QtGui.QImage.Format_RGB888)
  85. return qim.copy()
  86. return QtGui.QImage()
  87.  
  88. def image(self):
  89. return self._image
  90.  
  91. @QtCore.pyqtSlot(QtGui.QImage)
  92. def setImage(self, image):
  93. if self._image == image:
  94. return
  95. self._image = image
  96. self.imageReady.emit()
  97.  
  98. def index(self):
  99. return self._index
  100.  
  101. def setIndex(self, index):
  102. if self._index == index:
  103. return
  104. self._index = index
  105. self.indexChanged.emit()
  106.  
  107. @QtCore.pyqtProperty(QtQml.QQmlListProperty)
  108. def filters(self):
  109. return QtQml.QQmlListProperty(CVAbstractFilter, self, self.m_filters)
  110.  
  111.  
  112.  
  113.  
  114. image = QtCore.pyqtProperty(QtGui.QImage, fget=image, notify=imageReady)
  115. index = QtCore.pyqtProperty(int, fget=index, fset=setIndex, notify=indexChanged)

PyCVQML/cvitem.py

  1. from PyQt5 import QtCore, QtGui, QtQuick
  2.  
  3.  
  4. class CVItem(QtQuick.QQuickPaintedItem):
  5. imageChanged = QtCore.pyqtSignal()
  6.  
  7. def __init__(self, parent=None):
  8. super(CVItem, self).__init__(parent)
  9. ## self.setRenderTarget(QtQuick.QQuickPaintedItem.FramebufferObject)
  10. self.m_image = QtGui.QImage()
  11.  
  12. def paint(self, painter):
  13. if self.m_image.isNull():
  14. return
  15. image = self.m_image.scaled(self.size().toSize())
  16. painter.drawImage(QtCore.QPoint(), image)
  17.  
  18. def image(self):
  19. return self.m_image
  20.  
  21. def setImage(self, image):
  22. if self.m_image == image:
  23. return
  24. self.m_image = image
  25. self.imageChanged.emit()
  26. self.update()
  27.  
  28. image = QtCore.pyqtProperty(QtGui.QImage, fget=image, fset=setImage, notify=imageChanged)

PyCVQML/ init .py

  1. from PyQt5 import QtQml
  2.  
  3. from .cvcapture import CVCapture, CVAbstractFilter
  4. from .cvitem import CVItem
  5.  
  6.  
  7. def registerTypes(uri="PyCVQML"):
  8. QtQml.qmlRegisterType(CVCapture, uri, 1, 0, "CVCapture")
  9. QtQml.qmlRegisterType(CVItem, uri, 1, 0, "CVItem")
1

Вам это нравится? Поделитесь в социальных сетях!

0

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь