Tabla de Contenidos

OpenCV

OpenCV es una biblioteca de Intel que contiene rutinas y clases para el desarrollo de Computer Vision e Image Processing para C\C++.

Introducción

Estructura de la librería

Cómo utilizarlo?

Al instalarlo o descomprimirlo (según la versión) encontramos en el destino al menos dos directorios principalesimportantes: bin (donde están las dll) y lib (donde están los lib), y luego dentro de cada directorio de módulo (cv, cvaux, cxcore…) existe su directorio include correspondiente, donde están las cabeceras para nuestro código. Aquí cómo incluirlas en el proyecto, aunque básicamente necesitarás, sobretodo, vincular el cxcore.lib y las que vayas utilizando.

GUI

Ventanas

En HighGUI existen un número elevado de funciones que nos serán de utilidad al trabajar con ventanas, sus controles y eventos.

Empecemos por cvNamedWindow, a la cual se le pasa una cadena de carácteres, identificadora de dicha ventana para futuros usos. El segundo parámetro es opcional, pudiendo pasarle la flag CV_WINDOW_AUTOSIZE (que si no es indicado es el valor dado).

Editar la ventana es fácil utilizando funciones como cvMoveWindow o cvResizeWindow, para poder acceder a ella desde la API sólo necesitaremos su handle, fácil de coger utilizando la función cvGetWindowHandle. Podemos hacer la acción inversa (coger el nombre de la ventana utilizando su handle) ocn la función cvGetWindowName.

Funciones como cvDestroyAllWindows o cvDestroyWindow se utilizarán para cerrar la ventana por código.

Control de teclado y ratón

Teclado

Para controlar el teclado existe una única función, la cvWaitKey (delay=0), dicha función hace lo que su mismo nombre indica: esperar a que se pulse una tecla, esperará el tiempo que se le pase por parámetro (eternamente si este es 0).

Para hacer que el programa continue si el usuario no ha pulsado una tecla se la llama con delay != 0 y se mira su retorno.

Ratón

Para gestionar el control del ratón hay que definir una función para ello mediante la función cvSetMouseCallback, nuestra función tendrá que ser definida como void (nombre) (int event, int x, int y, int flags, void* param) donde x e y son las coordenadas actuales del mouse (en la imágen, no la ventana), event el evento lanzado (CV_EVENT_MOUSEMOVE, CV_EVENT_LBUTTONDOWN, CV_EVENT_MBUTTONUP…), los flags son una combinación de acciones realizadas durante el evento (CV_EVENT_FLAG_RBUTTON, CV_EVENT_FLAG_ALTKEY…) y param datos que el usuario quiere enviar a la función.

Para llamar a cvSetMouseCallback hay que pasle tres parámetros:

  1. El nombre de la ventana que ha de gestionar.
  2. El nombre de la función.
  3. Lo que el usuario quiera mandar a la función.
void on_mouse (int event, int x, int y, int flags, void* param) { ... }
void  main () {
  cvSetMouseCallback("LkDemo", on_mouse, 0);
...

Controles

Podemos colocar y tratar una barra de números en una ventana creada con OpenCV utilizando las funciones cvCreateTrackbar, cvGetTrackbarPos y cvSetTrackbarPos.

Funciones y tipos básicos

Tipos básicos

Funciones de utilidad

Imágenes

La clase IplImage representa una imágen cualquiera, para cargar sobre ella un archivo es tan sencillo como llamar a cvLoadImage pasándole como único parámetro el nombre de dicho archivo, esta función devolverá el IplImage* correspondiente con su formato determinado por el archivo cargado. Para guardar la imágen es igual de fácil, sólo hay que llamar a cvSaveImage, función que recibe el nombre de la nueva imágen y un IplImage*, fácil no?

Las propiedades de un IplImage incluyen el tamaño (height y width), los bytes correspondientes a la imágen (imageData)…

Para mostrar una imágen en una ventana (ya creada) llamaremos a la función cvShowImage con dos parámetros, el primero la cadena de carácteres identificadora de la ventana creada con cvNamedWindow y el segundo un IplImage*. Si la imágen se muestra en una ventana que se creó indicando que el tamaño es automático (con CV_WINDOW_AUTOSIZE) entonces la ventana se redimensiona al tamaño de la imágen (y queda la ventana como no-redimensionable), si no, la imágen se redimensiona al tamaño de la ventana.

Más cosas…

Una vez acabemos el trabajo con una imágen deberemos liberar los datos utilizados de memoria, para ello utilizamos la función cvReleaseImage.

cvNamedWindow("prueba");
IplImage* img = cvLoadImage("airplane.jpg");
cvShowImage("prueba", img);
cvWaitKey();

Dibujar sobre una imágen

A todas las funciones de dibujo podemos pasarle como parámetro una IplImage (básicamente aceptan un CvArr), que podemos crear mediante cvCreateImage, por lo que no nos será complejo realizar dibujos.
El color puede ser indicado mediante la macro CV_RGB o la función cvScalar.
Para dibujar formas:

Para dibujar texto:

Trabajar con la cam

Las siguientes funciones las encontraremos en la cabecera cvcam.h necesitando vincular la cvcam.lib.
La función cvCaptureFromCAM es la encargada de iniciar una captura de la webcam, se le puede pasar (opcionalmente) un valor numérico para indicar el número de cámara que se utilizará; para saber cuantas CAMs tiene disponible la máquina haremos una llamada a cvcamGetCamerasCount. El tipo que representa una captura, ya sea de la cam o de un archivo de video (para hacerla de un archivo de video hay que llamar a cvCaptureFromFile) es CvCapture. Una vez tenemos una CvCapture la podemos pasar a cvQueryFrame y nos devolverá la última IplImage. Cuando acabemos con el uso de la cámara no debemos olvidar liberar la CvCapture llamando a cvReleaseCapture.

Podemos crear una CvCapture utilizando también las funciones de la HighGUI (que no nos dan tanto control sobre la cámara) cvCreateCameraCapture (para capturar desde la cam, requiere como argumento el índice de la cámara) o cvCreateFileCapture (para capturar desde un archivo). También podremos definir las propiedades de la captura con cvSetCaptureProperty (o consultarlas con cvGetCaptureProperty), esta función requiere de 3 parámetros: un puntero a la CvCapture, el id de la propiedad a cambiar (ver más abajo las Propiedades de una captura) y el valor asignado.

CvCapture* cpa = cvCreateCameraCapture(0);
cvNamedWindow("winprueba");
do {
  IplImage* img = cvQueryFrame(cpa);
  cvShowImage("winprueba", img);
  cvWaitKey (30);
} while (1);
cvReleaseCapture(&cpa);

Mayor control con cvcam

Aunque con la HighGUI podemos manejar la cámara la cvcam nos dá mayor control sobre esta mediante un mayor número de funciones. Para que estas funcionen el sistema ha de tener registrados los filtros de DirectShow CalibFilter.ax y ProxyTrans.ax que vienen con OpenCV, para saber cómo registrarlos miralo aquí.

Una vez hemos llamado a cvcamGetCamerasCount y asignado las propiedades de la cámara deseadas mediante cvcamSetProperty (es importante activar el enable y al render) entonces llamaremos a cvcamInit() para acabar de inicializar la cámara. Para empezar a grabar tenemos la función cvcamStart y para acabar cvcamStop. Podemos pausar y reanudar el trabajo con la cam utilizando cvcamPause y cvcamResume.

Otras funciones de cvcam:

Es importante indicar que la primera llamada ha de ser a cvcamGetCamerasCount para que se inicialice el cvcam.

int ncams = cvcamGetCamerasCount();
cvNamedWindow ("test");
HWND hwnd = (HWND)cvGetWindowHandle("test");
cvcamSetProperty(0, CVCAM_PROP_ENABLE, CVCAMTRUE);
cvcamSetProperty(0, CVCAM_PROP_RENDER, CVCAMTRUE);
cvcamSetProperty(0, CVCAM_PROP_WINDOW, &hwnd);
cvcamInit();
cvcamStart();
for (;;);
cvcamStop( );
cvcamExit( );

Propiedades de la cámara

Son funciones que nos permiten definir\consultar propiedades de la cámara, las properties vienen dadas por los siguientes identificadores:

Propiedades de una captura

Tratamiento de imágenes

Conceptos

Acciones básicas sobre imágenes

Para indicar sobre qué área de la imágen vamos a trabajar (Region Of Interest) utilizaremos la función cvSetImageROI que recibe la imágen y un CvRect que sería dicha región, a partir de entonces la imágen sólo sería esa región hasta que llamemos a cvResetImageROI. En cualquier momento podemos llamar a cvGetImageROI para saber la Region of Interest actual. Las mismas funciones existen para el COI (Channel Of Interest), podemos escoger sobre qué canal de la imágen trabajaremos.

Funciones como cvSet, cvSetZero o cvCopy asignan o copias bloques de una imágen. Por ejemplo la primera, cvSet, asigna un CvScalar a una imágen, el cvSetZero asigna a 0 los valores de color y el cvCopycopia de una imágen a otra.

CvRect rect = cvRect(0, 0, 200, 200 );
cvSetImageROI(img, rect);
cvSetZero(img);
cvResetImageROI(img);

Histogramas

Un histograma es una gráfica estadística que muestra las frecuencias de los valores de una variable. El histograma de una imágen es un histograma que corresponde a los valores de los píxels de dicha imágen, generalmente el número de píxels se coloca en vertical y su valor de brillo en horizontal, por ejemplo, si una imágen está en escala de grises los rangos se localizarán en la parte horizontal que corresponda al gris. También existe el histograma de color, que representa la distribución de colores, pero no es tan utilizado como el histograma de imágen que nos permite variar el brillo y el contraste de forma sencilla utilizando el método histogram equalization.

Notas