Как объединить 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
версии?)