PyQt Lab est un outil puissant qui permet aux développeurs de créer des applications interactives et des interfaces graphiques. Il combine OpenCV et une webcam pour capturer le flux vidéo et le traiter. Grâce à cet outil, les développeurs peuvent créer des applications qui peuvent détecter des objets, reconnaître des visages et même suivre des mouvements. Dans cet article, nous allons examiner comment PyQt Lab peut être utilisé pour capturer le flux vidéo d’une webcam et le traiter avec OpenCV.
PyQt Lab’ : OPenCV + Webcam : Capture simple du flux vidéo
Par X. HINAULT – Juin 2013

Ce que l’on va faire ici
- Dans ce code PyQt, je montre comment réaliser une capture simple du flux vidéo en provenance d’une webcam et comment l’afficher dans une interface Qt (dans un QLabel via un QImage et Qpixmap).
- La clé de ce code est une classe de conversion de l’IplImage (format OpenCV) obtenu à partir de la webcam en un QImage. Ensuite, le QImage est transféré dans un QPixmap pour affichage dans un QLabel. Voir section « Dessin » pour les détails à ce sujet.
Pré-requis
- python 2.7
- pyqt4.x
- modules :
- Opencv
Matériel utilisé
- Webcam Logitech C270
Manip’ utile préalable
- S’assurer que la webcam fonctionne correctement, en ouvrant par exemple GuvcView sous Gnu/Linux. Une fois fait, bien refermer avant de lancer le code si-dessous par contre… !
Le fichier d’interface *.py
- Fichier obtenu automatiquement avec l’utilitaire pyuic4 à partir du fichier *.ui créé avec QtDesigner :
# Form implementation generated from reading ui file
#
# Created: Sun Jun 16 07:40:43 2013
# 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(331, 250)
self.labelImage = QtGui.QLabel(Form)
self.labelImage.setGeometry(QtCore.QRect(5, 5, 320, 240))
self.labelImage.setFrameShape(QtGui.QFrame.Box)
self.labelImage.setFrameShadow(QtGui.QFrame.Sunken)
self.labelImage.setText(_fromUtf8(« »))
self.labelImage.setObjectName(_fromUtf8(« labelImage »))
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(QtGui.QApplication.translate(« Form », « PyQt+Opencv+webcam : Capture image », 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
# -*- 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
import time # pour micros
#from cv2 import * # importe module OpenCV qui contient sous-module cv
import cv2.cv as cv # importe sous-module cv du module OpenCV
# import cv2 # importe le module OpenCV
# — importation du fichier de description GUI —
from tuto_pyqt_opencv_webcam_capture_image 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 —
#========= paramètres graphiques généraux ========
self.framerate=30 # nombre d’image par secondes (rafraîchissement de l’affichage)
self.widthCapture=320 # largeur image capture en pixels
self.heightCapture=240 # hauteur image capture en pixels
# la résolution utilisée doit être supportée par la webcam – 320×240 est un bon compromis –
# — Paramétrage des widgets de l’interface GUI si nécessaire —
# ..
# — Connexions entre signaux des widgets et fonctions
# connecte chaque signal utilisé des objets à l’appel de la fonction voulue
# ..
#— code actif initial
#======== config capture openCV ==========
#– initialisation de la caméra
self.indexCam=0 # index de la webcam à utiliser – voir ls /dev/video* – utiliser -1 si pas d’indice
self.webcam=cv.CaptureFromCAM(self.indexCam) # déclare l’objet capture sans désigner la caméra – remplace CreateCameraCapture
#print (self.webcam) # debug
cv.SetCaptureProperty(self.webcam,cv.CV_CAP_PROP_FRAME_HEIGHT,240) # définit hauteur image capture
cv.SetCaptureProperty(self.webcam,cv.CV_CAP_PROP_FRAME_WIDTH,320) # définit largeur image capture
#cv.SetCaptureProperty(self.webcam,cv.CV_CAP_PROP_FPS,30) # fixe le framerate hardware- pas toujours supporté par webcam
#self.iplImgSrc=cv.QueryFrame(self.webcam) # récupère un IplImage en provenance de la webcam # +/- premiere capture
# — Activation d’un Timer pour affichage image – fixe le fps d’affichage en fait —
self.timerRefresh=QTimer() # déclare un timer Qt
self.connect(self.timerRefresh, SIGNAL(« timeout() »), self.timerRefreshEvent) # connecte le signal timeOut de l’objet timer à l’appel de la fonction voulue
self.timerRefresh.start(int(1000/self.framerate)) # lance le timer – mettre délai assez court pour fps élevé
# les fonctions appelées, utilisées par les signaux
#def pushButtonClicked(self):
#print(« Bouton appuyé »)
# — les fonctions appelées, utilisées par les signaux hors widgets —
def timerRefreshEvent(self): # fonction appelée lors de la survenue d’un évènement Timer – nom fonction indiférrent
print(« Capture Image webcam »)
micros0=self.micros()
#self.iplImgSrc=cv.QueryFrame(self.webcam) # récupère un IplImage en provenance de la webcam – Grab + retrieve
if cv.GrabFrame(self.webcam) : # si une image est dispo
print (« frame dispo »)
self.iplImgSrc=cv.RetrieveFrame(self.webcam) # récupère un IplImage en provenance de la webcam
print (str(self.micros()-micros0) + » us »)
micros0=self.micros()
# affichage de l’image webcam
self.qImage = IplQImage(self.iplImgSrc) # récupère le IplImage dans un QImage
self.qPixmap=QPixmap.fromImage(self.qImage) # récupère le QImage dans QPixmap
self.labelImage.setPixmap(self.qPixmap) # affiche le QPixmap dans le QLabel
print (str(self.micros()-micros0) + » us »)
# autres fonctions actives
# fonction micros : renvoie le nombre de microsecondes courant de l’horloge système
def micros(self):
return(int(round(time.time() * 1000000))) # microsecondes de l’horloge système
# — classes utiles —
# — classe de conversion d’une iplImage en QImage
class IplQImage(QImage): # fonction qui étend la classe QImage
# IplQImage est une classe qui transforme un iplImage (OpenCV) en un QImage (Qt)
« » »
http://matthewshotton.wordpress.com/2011/03/31/python-opencv-iplimage-to-pyqt-qimage/
A class for converting iplimages to qimages
« » »
def __init__(self,iplimage):
# Rough-n-ready but it works dammit
alpha = cv.CreateMat(iplimage.height,iplimage.width, cv.CV_8UC1)
cv.Rectangle(alpha, (0, 0), (iplimage.width,iplimage.height), cv.ScalarAll(255) ,-1)
rgba = cv.CreateMat(iplimage.height, iplimage.width, cv.CV_8UC4)
cv.Set(rgba, (1, 2, 3, 4))
cv.MixChannels([iplimage, alpha],[rgba], [
(0, 0), # rgba[0] -> bgr[2]
(1, 1), # rgba[1] -> bgr[1]
(2, 2), # rgba[2] -> bgr[0]
(3, 3) # rgba[3] -> alpha[0]
])
self.__imagedata = rgba.tostring()
super(IplQImage,self).__init__(self.__imagedata, iplimage.width, iplimage.height, QImage.Format_RGB32)
# — fin class IplQImage
# 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
- Le flux de la webcam doit s’afficher dans la fenêtre.
Articles Liés
- Javascript : Graphique Dygraphs simple
Le Javascript est un langage de programmation très populaire et puissant qui permet aux développeurs…
- Javascript : Afficher 6 widgets graphiques fournis par une librairie graphique externe.
Le Javascript est un langage de programmation très populaire qui permet aux développeurs de créer…
- Javascript : Graphique Dygraphs : afficher date à partir unixtime
Le langage de programmation Javascript est très populaire et est utilisé pour créer des applications…