View  Edit  Attributes  History  Attach  Print  Search

PYQTLAB

PyQt Lab' : PyQt + OpenCV : Sélectionner un fichier image et afficher l'image avec OpenCV dans une interface PyQt

Par X. HINAULT - Juin 2013

Ce que l'on va faire ici

  • Dans ce code PyQt, une interface permettant de sélectionner un fichier image et afficher l'image avec OpenCV dans une interface PyQt. Ici, l'image est automatiquement redimensionnée en 320x240, quelque soit sa taille d'origine.

Pré-requis

Téléchargement :

$ cd scripts_pyqt
$ mkdir
$ cd
$ wget -4 -N
$ wget -4 -N

Le fichier d'interface *.py

  • Fichier obtenu automatiquement avec l'utilitaire pyuic4 à partir du fichier *.ui créé avec QtDesigner :
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file
#
# Created: Wed Dec 12 08:30:14 2012
#      by: PyQt4 UI code generator 4.9.1
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(337, 295)
        self.labelImage = QtGui.QLabel(Form)
        self.labelImage.setGeometry(QtCore.QRect(10, 10, 320, 240))
        self.labelImage.setFrameShape(QtGui.QFrame.Box)
        self.labelImage.setFrameShadow(QtGui.QFrame.Sunken)
        self.labelImage.setText(_fromUtf8(""))
        self.labelImage.setObjectName(_fromUtf8("labelImage"))
        self.pushButtonOuvrir = QtGui.QPushButton(Form)
        self.pushButtonOuvrir.setGeometry(QtCore.QRect(280, 260, 51, 27))
        self.pushButtonOuvrir.setObjectName(_fromUtf8("pushButtonOuvrir"))
        self.lineEditChemin = QtGui.QLineEdit(Form)
        self.lineEditChemin.setGeometry(QtCore.QRect(10, 260, 261, 23))
        self.lineEditChemin.setObjectName(_fromUtf8("lineEditChemin"))

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        Form.setWindowTitle(QtGui.QApplication.translate("Form", "load Image File", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonOuvrir.setText(QtGui.QApplication.translate("Form", "Ouvrir", None, QtGui.QApplication.UnicodeUTF8))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    Form = QtGui.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

 

Le fichier d'application *Main.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

# Par X. HINAULT - Tous droits réservés - GPLv3
# Déc 2012 - www.mon-club-elec.fr

# --- importation des modules utiles ---
from PyQt4.QtGui import *
from PyQt4.QtCore import * # inclut QTimer..

import os,sys
from cv2 import * # importe module OpenCV

sys.path.insert(0,'/home/xavier') # si pas path système
from pyqtcv import * # importe librairie perso comportant fonctions utiles pour utiliser opencv avec pyqt

# --- importation du fichier de description GUI ---
from tuto_pyqt_opencv_load_image_file import *

# --- classe principale du programme pyQt contenant le code actif ---
class myApp(QWidget, Ui_Form):
# la classe reçoit le Qwidget principal ET la classe Ui_Form définie dans *.py obtenu avec pyuic4

        # Note : ici self représente la classe

        def __init__(self, parent=None):
                QWidget.__init__(self) # initialise le Qwidget principal
                self.setupUi(parent) # Obligatoire

                #-- variables utiles --

                #Ici, personnalisez vos widgets si nécessaire en utilisant les noms définis dans QtDesigner

                #Réalisez les connexions supplémentaires entre signaux et slots
                # les widgets sont désignés sous la forme self.nom en utilisant les noms définis dans QtDesigner
                self.connect(self.pushButtonOuvrir, SIGNAL("clicked()"), self.pushButtonOuvrirClicked) # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue

                #--- code actif initial

        # les fonctions appelées, utilisées par les signaux
        def pushButtonOuvrirClicked(self):
                print("Bouton OUVRIR appuyé") # debug

                #self.filename=QFileDialog.getOpenFileName(self, 'Ouvrir fichier', os.getenv('HOME')) # ouvre l'interface fichier
                self.filename=QFileDialog.getOpenFileName(self, 'Ouvrir fichier', QDir.currentPath()) # ouvre l'interface fichier
                # getOpenFileName ouvre le fichier sans l'effacer et getSaveFileName l'efface si il existe


                print(self.filename) # debug
                self.lineEditChemin.setText(self.filename) # affiche le chemin du fichier dans le champ texte          

                # charge de l'image
                self.cvImageSrc=cv.LoadImage(str(self.filename), cv.CV_LOAD_IMAGE_COLOR) # charge l'image sous forme d'une iplImage 3 canaux

                # crée une image OpenCV de la taille du label d'affichage
                self.cvImage=cv.CreateImage((self.labelImage.width(), self.labelImage.height()), cv.IPL_DEPTH_8U, 3)

                # redimensionne image source aux dimensions du label d'affichage
                cv.Resize(self.cvImageSrc,self.cvImage, cv.CV_INTER_LINEAR)

                # affiche l'image dans Qt
                self.qImage=IplToQImage(self.cvImage) # récupère l'IplImage dans un QImage
                self.qPixmap=QPixmap.fromImage(self.qImage) # récupère le QImage dans un QPixmap
                self.labelImage.setPixmap(self.qPixmap) # affiche l'image dans le label
                # NB : pour éviter les problèmes, les objets de manipulation d'image doivent être "self"


        # autres fonctions actives
        # ...

# fonction principale exécutant l'application Qt                       
def main(args):
        a=QApplication(args) # crée l'objet application
        f=QWidget() # crée le QWidget racine
        c=myApp(f) # appelle la classe contenant le code de l'application
        f.show() # affiche la fenêtre QWidget
        r=a.exec_() # lance l'exécution de l'application
        return r

# pour rendre le fichier *.py exécutable
if __name__=="__main__": # pour rendre le code exécutable
        main(sys.argv) # appelle la fonction main
 

Utilisation

  • Les 2 fichiers suivants sont à enregistrer dans un même répertoire, l'un en nom.py et l'autre en nomMain.py.
  • Puis lancer l'application depuis Geany ou équivalent, en exécutant le fichier nomMain.py
  • Cliquer sur ouvrir, sélectionner un fichier : l'image s'affiche.