J'ai besoin d'effectuer beaucoup d'opérations sur une image. J'ai donc utilisé OpenCV. OpenCV est très efficace dans le traitement d'image, mais il n'est pas trop bon de présenter une interface graphique appropriée. J'ai donc décidé d'utiliser PyQt pour dessiner une interface graphique personnalisée et OpenCV pour traiter mon image.
J'ai créé un programme très simple que vous avez directement choisi dans la documentation. Je lis simplement une image jpg
et je l'enregistre au format png
en appuyant sur la touche s
.
Mon objectif est de remplacer la touche s
par un bouton à appuyer pour effectuer la même action en utilisant PyQt. De plus, je veux que la fenêtre affichée par PyQt ait le même comportement qu'OpenCV: principalement, la fonction imshow()
affiche une fenêtre qui correspond à la taille de l'image.
Voici mon code simple 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()
Production:
Voici un code PyQt simple pour dessiner une fenêtre simple:
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()
Comment puis-je mélanger les 2 codes pour atteindre mon objectif?
Modifié du code basé sur votre message, je n'ai pas utilisé l'Opencv pour rendre l'image, mais plutôt QPixmap pour la rendre. puis utilisez KeyPressEvent pour capturer l'entrée utilisateur.
# -*- 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_()
Vous pouvez créer un QImage
directement à partir des données d'image lues par OpenCV, le convertir en QPixmap
en utilisant QPixmap.fromImage
, Puis l'utiliser pour définir le pixmap d'un QLabel
en utilisant la méthode setPixmap
.
Cette page montre comment afficher un flux de webcam en utilisant PySide et OpenVC: https://Gist.github.com/bsdnoobz/84640 . Je l'ai également fait fonctionner pour les vidéos, en commentant ces deux lignes
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())
et à la place en utilisant
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)
sur l'image vidéo (où bgr_frame
est l'image obtenue avec self.capture.read()
).
(Notez qu'il existe différentes conventions de nommage et d'espace de noms pour les constantes OpenCV en cours ici, peut-être en raison de versions différentes de cv2
?)