¡Esta es una revisión vieja del documento!
OpenCV es una biblioteca de Intel que contiene rutinas y clases para el desarrollo de Computer Vision e Image Processing para C\C++.
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.
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.
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.
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:
void on_mouse (int event, int x, int y, int flags, void* param) { ... } void main () { cvSetMouseCallback("LkDemo", on_mouse, 0); ...
Podemos colocar y tratar una barra de números en una ventana creada con OpenCV utilizando las funciones cvCreateTrackbar, cvGetTrackbarPos y cvSetTrackbarPos.
height y width, podemos crear una instancia utilizando la función cvSize que recibe estos dos argumentos.x e y, igual que con CvSize podemos crear una instancia utilizando cvPoint.
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…
IPL_DEPTH_XXX) y el número de canales de color (1, 2, 3 o 4).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();
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:
(CvFont* font, int font_face, double hscale, double vscale, double shear=0, int thickness=1, int line_type=8), la cual inicializa una instancia CvFont, con una font_face (que está definida como CV_FONT_HERSHEY_XXX), hscale y vscale corresponden al tamaño, shear a si está en cursiva o no (1.0 serían unos 45º) y line_type corresponde al tipo de línea que utiliza (ver cómo dibujar líneas).(CvArr* img, const char* text, CvPoint org, const CvFont* font, CvScalar color ) escribe en la imágen img el texto text en la posición org utilizando la fuente font y el color color.
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);
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( );
cvcamGetProperty(int cameraindex, const char* property, void* value)cvcamSetProperty(int cameraindex, const char* property, void* value)Son funciones que nos permiten definir\consultar propiedades de la cámara, las properties vienen dadas por los siguientes identificadores:
CVCAM_PROP_ENABLE - Selecciona\Deselecciona la cámara (hay que pasarle CVCAMTRUE o CVCAMFALSE).CVCAM_PROP_RENDER - Renderiza la cam (hay que pasarle CVCAMTRUE o CVCAMFALSE).CVCAM_PROP_WINDOW - Selecciona la ventana sobre la que se renderizará la captura (hay que pasarle un HWND).CVCAM_PROP_CALLBACK - Asigna una funcción void (*callback)(IplImage* image) para que trate la captura.CVCAM_DESCRIPTION - Recoge en una CameraDescription datos de la cam.CVCAM_VIDEOFORMATCVCAM_CAMERAPROPSCVCAM_RNDWIDTHCVCAM_RNDHEIGHTCVCAM_STEREO_CALLBACKCVCAM_PROP_RAWCVCAM_PROP_SETFORMATCV_CAP_PROP_POS_MSEC - Tiempo en milisegundos desde el principio.CV_CAP_PROP_POS_FRAMES - Posición en frames (sólo para capturas desde ficheros).CV_CAP_PROP_POS_AVI_RATIO - Posición en un archivo en un ratio de 0-1.CV_CAP_PROP_FRAME_WIDTH - Ancho de un frame (sólo para capturas desde cámaras).CV_CAP_PROP_FRAME_HEIGHT - Alto de un frame (sólo para capturas desde cámaras).CV_CAP_PROP_FPS - Framerate (sólo para capturas desde cámaras).CV_CAP_PROP_FOURCC - código de 4 carácteres del codec (sólo para capturas desde cámaras).
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);
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.
libcv, libcvaux y libhighgui.