Как объединить OpenCV с PyQt для создания простого графического интерфейса?

Мне нужно выполнить много операций над изображением. Поэтому я использовал OpenCV. OpenCV очень эффективен в обработке изображений, однако не слишком хорошо представлять подходящий графический интерфейс. Поэтому я решил использовать PyQt для рисования пользовательского интерфейса и OpenCV для обработки моего изображения.

Я создал очень простую программу, которую вы выбрали из документации. Я просто читаю jpg изображение и сохранить его в png отформатировать нажатием клавиши s,

Моя цель - заменить ключ s с кнопкой, чтобы нажать, чтобы выполнить то же действие, используя PyQt. Кроме того, я хочу, чтобы окно, отображаемое PyQt, имело то же поведение, что и OpenCV: в основном, функция imshow() отображает окно, которое соответствует размеру изображения.

Вот мой простой код OpenCV:

import numpy 
import cv2

class LoadImage:
    def loadImage(self):
        img = cv2.imread('photo.jpg')
        cv2.imshow('Image on a window',img)
        k = cv2.waitKey(0)
        if k == 27:
            cv2.destroyAllWindows()
        elif k == ord('s'):
            cv2.imwrite('photopng.png',img)
            cv2.destroyAllWindows()

if __name__=="__main__":
    LI=LoadImage()
    LI.loadImage()

Выход:

Вот простой код PyQt для рисования простого окна:

import sys
from PyQt4 import QtGui

class DrawWindow:
    def drawWindow(self):
        app=QtGui.QApplication(sys.argv)
        w=QtGui.QWidget()
        #w.resize(250,250)
        w.move(300,300)
        w.setWindowTitle("Simple Window")
        w.show()

        sys.exit(app.exec_())

if __name__=="__main__":
    DW=DrawWindow()
    DW.drawWindow()

Как я могу смешать 2 кода для достижения моей цели?

1 ответ

Изменив некоторый код на основе вашего поста, я не использовал Opencv для рендеринга изображения, а использовал QPixmap для его рендеринга. затем используйте KeyPressEvent для захвата ввода пользователя.

# -*- coding: utf-8 -*-


import numpy
import cv2
from PyQt4.QtGui import *
from PyQt4.QtCore import *


class MyDialog(QDialog):
    def __init__(self, parent=None):
        super(MyDialog, self).__init__(parent)

        self.cvImage = cv2.imread(r'cat.jpg')
        height, width, byteValue = self.cvImage.shape
        byteValue = byteValue * width

        cv2.cvtColor(self.cvImage, cv2.COLOR_BGR2RGB, self.cvImage)

        self.mQImage = QImage(self.cvImage, width, height, byteValue, QImage.Format_RGB888)

    def paintEvent(self, QPaintEvent):
        painter = QPainter()
        painter.begin(self)
        painter.drawImage(0, 0, self.mQImage)
        painter.end()

    def keyPressEvent(self, QKeyEvent):
        super(MyDialog, self).keyPressEvent(QKeyEvent)
        if 's' == QKeyEvent.text():
            cv2.imwrite("cat2.png", self.cvImage)
        else:
            app.exit(1)


if __name__=="__main__":
    import sys
    app = QApplication(sys.argv)
    w = MyDialog()
    w.resize(600, 400)
    w.show()
    app.exec_()

Вы можете создать QImage непосредственно из данных изображения, считываемых OpenCV, преобразовать их в QPixmap с помощью QPixmap.fromImage а затем используйте это, чтобы установить растровое изображение QLabel используя setPixmap метод.

На этой странице показано, как просмотреть канал веб-камеры с помощью PySide и OpenVC: https://gist.github.com/bsdnoobz/8464000. Я заставил это работать и для видео, закомментировав эти две строки

self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, self.video_size.width())
self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, self.video_size.height())

и вместо этого используя

resized_bgr_frame = cv2.resize(
    bgr_frame,
    (self.video_size.width(), self.video_size.height()),
    interpolation=cv2.INTER_CUBIC if self.video_size.width() > bgr_frame.shape[1] else cv2.INTER_AREA)

на видеокадре (где bgr_frame это кадр, который был получен с self.capture.read()).

(Обратите внимание, что здесь используются некоторые другие соглашения об именах и пространствах имен для констант OpenCV, возможно, из-за различий cv2 версии?)

Другие вопросы по тегам