Está en la página 1de 4

OpenCV y Qt

Si estamos desarrollando una aplicación gráfica en Qt debemos tomar una serie de


medidas para poder emplear la librería OpenCV desde ella:

Conversión de QImage en cv::Mat

Las imágenes de las que haremos uso son instancias de la clase QImage, propia del
framework Qt. Sin embargo las funciones, clases y métodos de OpenCV esperan objetos
cv::Mat. Para convertir entre un formato y otro podemos emplear el proyecto
QtOpenCV de Debao Zhang (licencia MIT)

Para utilizarlo sólo necesitamos:

1. Descargar en el directorio del proyecto los archivos:

 cvmatandqimage.cpp

 cvmatandqimage.h

 opencv.pri

1. Abrir el archivo .pro del proyecto y añadir al final la línea:


2. include(opencv.pri)

Los archivos .pri tienen el mismo formato que los .pro pero están pensados para ser
incluidos por estos últimos. En nuestro caso el archivo opencv.pri contiene
información sobre como incorporar los archivos cvmatandqimage.cpp y
cvmatandqimage.h al proyecto, haciendo que las funciones por ellos definidas estén
disponibles para nuestra aplicación.

Tal y como se comenta en el archivo README.md de QtOpenCV, en el proyecto se


definen dos funciones:

que podemos usar para convertir objetos QImage a cv::Mat y viceversa.

Incorporar la librería OpenCV al proyecto

Aunque ya hemos incorporado QtOpenCV a nuestro proyecto para la conversión entre


formatos de imagen, aun no hemos añadido la librería OpenCV propiamente dicha:

El archivo opencv.pri incluido anteriormente facilita el añadir OpenCV al proyecto. Lo


único que tenemos que hacer es editar el archivo .pro e incorporar al final la línea
add_opencv_modules(core video imgproc). Si estamos trabajando en Windows, la
línea a incorporar debe ser add_opencv_modules(core video imgproc, 2.4.4),
donde 2.4.4 debe sustituirse por el número de la versión actualmente instalada de
OpenCV. Esto es un requisito en dichos sistemas ya que ese número se usa para
componer el nombre de las librerías .dll con las que debe enlazarse el ejecutable del
proyecto.
En la introducción de OpenCV se explica que el paquete está divido a su vez en
distintos módulos o librerías, cada uno de los cuales está dedicado a un tipo de tarea
específico. En nuestro caso concreto el módulo video incluye las clases y funciones de
supresión del fondo que nos interesa utilizar, mientras que imgproc contiene las
operaciones morfológicas y de detección de contornos.

Incorporar manualmente la librería OpenCV al proyecto

Si por cualquier motivo no estuviéramos haciendo uso de los archivos .pri tendríamos
que incorporar la librería al proyecto manualmente:

En Linux y Mac OS X esto se puede hacer como un paquete instalado en el sistema:

1. En el menú contextual del proyecto (botón derecho sobre el proyecto)


seleccionar Add Library…/System package.
2. En el paso posterior indicar opencv como nombre del paquete. Obviamente la
librería tiene que haber sido instalada previamente usando el procedimiento
usual de nuestra distribución.

Mientras que en Windows este recurso no existe, por lo que la librería suele
incorporarse al proyecto como librería externa:

1. En el menú contextual del proyecto (botón derecho sobre el proyecto)


seleccionar Add Library…/External library.
2. Indicar el archivo de la librería (Library file) que queremos incorporar y el
directorio de cabeceras (Include Path). Como lo estamos haciendo para
Windows, sólo tenemos que tener marcada dicha opción en la lista de
plataformas soportadas. Por lo general:

 Librerías en C:\opencv\build\<ARQUITECTURA>\mingw\lib:
 libopencv_core<VERSION>.dll.a

 libopencv_video<VERSION>.dll.a

 Ruta de las cabeceras: C:\opencv\build\include

Para ambos sistemas, al terminar se nos abrirá el archivo .pro del proyecto con los
cambios correspondientes realizados. Debemos guardarlo para dar por finalizada la
incorporación de la librería.

QImage vs QPixmap

Una instancia de QPixmap es una representación de una imagen optimizada para ser
mostrada. Esto significa que en muchos sistemas sus características dependen de las de
la pantalla (p. ej. su profundida de color puede tener que ser la misma que la que
actualmente tiene el adaptador gráfico: 8 bits, 16 bits, 32 bits, etc.) y que internamente
se implementa mediante algún tipo de objeto del lado del servidor gráfico cuya función
es representar a las imágenes de cara al resto del sistema de ventanas. Por lo tanto, los
píxeles de un objeto QPixmap no son accesibles directamente por parte del aplicación.
Una instancia de QImage es una representación independiente del hardware de una
imagen. Básicamente permite leer y escribir imágenes desde un archivo y manipular los
píxeles directamente, sin que las características actuales del adaptador gráfico tengan
nada que ver. Los datos de la imagen se almacenan en el lado de la aplicación, por lo
que son accesibles a esta en todo momento.

Normalmente la clase QImage se utiliza para cargar una imagen desde un archivo,
opcionalmente manipular los píxeles y después convertirla a un objeto QPixmap para
mostrarla en la pantalla.

En nuestro caso existen dos motivos fundamentales para utilizar QImage en lugar de
QPixmap:

 Para convertir la imagen a un objeto cv::Mat de OpenCV se necesita acceso a


los datos de los píxeles. Como hemos comentado, eso sólo es posible con la
clase QImage.
 Generalmente un objeto QPixmap encapsula el acceso a algún tipo de recurso del
servidor gráfico, con el que la aplicación se comunica a través del hilo GUI (el
hilo principal de la aplicación). Puesto que en muchos sistemas operativos no es
seguro comunicarse con el servidor gráfico a través de un hilo diferente a ese,
cualquier manipulación de un objeto QPixmap fuera del hilo principal puede dar
lugar a efectos inesperados. Dado que queremos transferir las imágenes a un hilo
de trabajo para su procesamiento, parece que lo más seguro es utilizar la clase
QImage.

Detección de movimiento

Con acceso a las clases y funciones de OpenCV desde nuestra aplicación, podemos
pasar a resolver el problema que nos habíamos propuesto; detectar movimiento en una
secuencia de vídeo.

Como ocurre con muchas otras tareas en el campo de la visión por computador, esta se
puede resolver de múltiples maneras. Además es muy común que en cada técnica
posible haya una decena de parámetros que den resultados diferentes según como los
ajustemos.

Nosotros nos centraremos en solución concreta:

Donde suponemos que previamente hemos convertido todas las imágenes de QImage a
cv::Mat y las hemos almacenado en un vector.

Al final de cada iteración del bucle tenemos para cada imagen un vector de contornos,
donde cada uno es un vector de puntos. Con los contornos se pueden hacer múltiples
operaciones. Por ejemplo calcular el rectángulo que contiene a cada uno (bounding box)
con cv::boundingRect() para pintarlos sobre la imagen antes de mostrársela al
usuario.

Referencias
 OpenCV
 QtOpenCV
 QPixmap: It is not safe to use pixmaps outside the GUI thread

También podría gustarte