Powered by Blogger.

Wednesday, April 20, 2005

Tag: , , , ,

OpenCV I - Highgui

En este tutorial vamos ha explicar como comenzar ha trabajar con openCV, que es una librería de programación para visión por computador. Vamos a introducir la creación de ventanas en openCV, así como la carga de un archivo de imagen.

Para la creación de una ventana basta con llamar a la siguiente función:

int cvNamedWindow(const char* name, unsigned long flags);

A la que se le pasa como name una cadena de caracteres que identificará de froma única a nuestra ventana y servirá como titulo de nuestra ventana también. El segundo parametro define las propiedades de la ventana, CV_WINDOW_AUTOSIZE o 1 para ajustar la ventana a la imagen mostrada o 0 en otro caso.

Una vez creada nuestra ventana, o ventanas para cargar una imagen simplemente debemos llamar a la función:

IplImage* cvLoadImage( const char* filename, int iscolor CV_DEFAULT(1));

Que como primer parámetro le pasaremos una cadena de caracteres de la imagen que queremos cargar, y como segundo parámetro un valor entero mayor que 0 si queremos que la imagen se carge con 3 canales (rojo, verde y azul), igual a 0 si queremos que se carge con un canal, en escala de grises, o menor que 0 si queremos que se carge según la cabecera del archivo. Los archivos soportados por OpenCV son: Windows bitmaps - BMP, DIB; JPEG files - JPEG, JPG, JPE; Portable Network Graphics - PNG; Portable image format - PBM, PGM, PPM; Sun rasters - SR, RAS; TIFF files - TIFF, TIF. El valor que devuelve esta función es un puntero a una estructura de una imagen (IplImage).

Solo nos falta mostrar una imagen en nuestra ventana que hemos creado, esto se realiza de forma simple con la llamada a la función:

void cvShowImage( const char* name, const CvArr* image );

En la que se le pasa como primer parámetro una cadena de carácteres que identifican a la ventana donde queremos mostrar la imagen y como segundo parámetro la imagen que queremos mostrar.

En el siguiente ejemplo vamos a cargar la misma imagen en rgb y en escala de grises y mostrarlas en dos ventanas distintas, el resultado lo podemos ver en la figura 1:
#include "highgui.h"

#define ventana "Ventana1"

#define ventana1 "Ventana2"
int main(int argc, char* argv[])

{
//Comprobamos si han pasado una image como parametro, sino una por defecto

char* filename = argc >= 2 ? argv[1] : (char*)"lena.jpg";

//cargamos la imagen en RGB

IplImage* imagen;

//(archivo,int a) a>0:RGB; a=0:Escala Grises; a<0:la de la imagen

imagen=cvLoadImage(filename,1);

//Cargamos la imagen en Escala de grises

IplImage* imagen1;

//(archivo,int a) a>0:RGB; a=0:Escala Grises; a<0:la de la imagen

imagen1=cvLoadImage(filename,0);

cvNamedWindow(ventana,0);

cvNamedWindow(ventana1,0);

//Mostramos la imagen en la ventana

cvShowImage(ventana,imagen);

cvShowImage(ventana1,imagen1);

for(;;)

{
int key;

key = cvWaitKey(0);

if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC', q o Q
break;


}

cvDestroyAllWindows();//Destruimos todas las ventanas

return 0;

}

figura 1
Figura 1

About David Millán Escrivá

David completed his studies in Universidad Politecnica de Valencia in IT with a Master's degree in artificial intelligence, computer graphics, and pattern recognition, focusing on pattern recognition and Computer Vision. David has more than 15 years of experience in IT, with more than ten years of experience in Computer Vision, computer graphics, and pattern recognition, working on different projects and start-ups, applying his knowledge of Computer Vision, optical character recognition, and augmented reality. Co-Author of two OpenCV books and reviewer of few more.

59 comments:

  1. Que buen tutorial, gracias, sirvio de mucha ayuda.
    Tienes algún tutorial para procesamiento de imagenes desde una webcam?, muchas gracias de antemano.

    Saludos

    ReplyDelete
  2. Hola Víctor, me alegro mucho que te haya sido de ayuda, como me comentas de algún tutorial de procesamiento desde una webcam, pues nada, algo muy introductorio, es muy muy básico, pero poco a poco iré haciendo más tutoriales.

    http://blog.damiles.com/?p=67

    ReplyDelete
  3. hola estoy tratando de empesar con el open cv y dev cpp pero no puedo compilar ni el mas facil ejemplo.. alguien me puede ayudar

    ReplyDelete
  4. Mariano, para poderte ayudar, primero debes decirnos cual es el problema, que error te da al compilar.

    ReplyDelete
  5. Hi dear Sir, I've been reading with lots of interest ur tutorials about openCV, am new in this kinda programmation and i'd like to work on computer vision, especially in gait recognition. However i dont even know how to read an image(extract pixels and store them in a matrix) with openCv (include vc++).
    So I kindly ask if u can help me with a code or a good tutorial. thanks in advance
    ps: my goal is to rewrite the canonical view synthesis and the gait energy image source code !!

    ReplyDelete
  6. bien grasias ya resolvi el problema es que en dev cpp hay que configurarlo desde opciones de proyecto

    ReplyDelete
  7. Hi Eric, if you read the docs folder of OpenCV in faq section of index.html have the basic instructions to read and write in the image array.

    This is a copy/paste of faq doc.

    How to access image pixels

    * Suppose, we have 8-bit 1-channel image I (IplImage* img):

    I(x,y) ~ ((uchar*)(img->imageData + img->widthStep*y))[x]

    * Suppose, we have 8-bit 3-channel image I (IplImage* img):

    I(x,y)blue ~ ((uchar*)(img->imageData + img->widthStep*y))[x*3]
    I(x,y)green ~ ((uchar*)(img->imageData + img->widthStep*y))[x*3+1]
    I(x,y)red ~ ((uchar*)(img->imageData + img->widthStep*y))[x*3+2]

    e.g. increasing brightness of point (100,100) by 30 can be done this way:

    CvPoint pt = {100,100};
    ((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3] += 30;
    ((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3+1] += 30;
    ((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3+2] += 30;

    or more efficiently

    CvPoint pt = {100,100};
    uchar* temp_ptr = &((uchar*)(img->imageData + img->widthStep*pt.y))[x*3];
    temp_ptr[0] += 30;
    temp_ptr[1] += 30;
    temp_ptr[2] += 30;

    * Suppose, we have 32-bit floating point, 1-channel image I (IplImage* img):

    I(x,y) ~ ((float*)(img->imageData + img->widthStep*y))[x]

    * Now, the general case: suppose, we have N-channel image of type T:

    I(x,y)c ~ ((T*)(img->imageData + img->widthStep*y))[x*N + c]
    or you may use macro CV_IMAGE_ELEM( image_header, elemtype, y, x_Nc )
    I(x,y)c ~ CV_IMAGE_ELEM( img, T, y, x*N + c )

    ReplyDelete
  8. Thx a lot Sir,
    but this look kinda fuzzy for me !!! the initialisation variables, and even the code is not complete, i mean how to display the pixels on the screen ! can i pls hv a link to that faq section? i've looked everywhere in the blog and couldnt find it.

    ReplyDelete
  9. Sorry, i didnt know you were talking about the faq in the docs file located on my computer :)
    Thx for the hint!

    ReplyDelete
  10. hola ya estoy compilando con open cv en dev cpp pero por ultimo me a surgido un problema me sale a cualquier programa queado con open cv un error que dice :
    la aplicacion no ha podido inicializar correctamente "(0xc0150002).Haga clic en aceptar para terminar la aplicacion"

    ReplyDelete
  11. Hola mariano, no se realmente porque tendrás ese problema, mira este enlace a ver si te soluciona algo http://tech.vkapoor.com/2007/12/error-code-0xc0150002-application.html

    ReplyDelete
  12. Seguramente sea porque no has enlazado correctamente las librerías de openCV.

    Si trabajas en windows es posible que necesites poner las librerías en la carpeta del ejecutable.

    P.D: cuida un poco la ortografía. xD

    ReplyDelete
  13. Era la opción más lógica kazaa. Pero hace años que no trabajo en windows.

    ReplyDelete
  14. uso windows muy a mi pesar tengo el ue sp2 el problema sale incluso en el ejemplo de arriba para ejecutar coloco las dll en el mismo directorio la otra solucion seria enlinux pero el unico que manejo es el elive pero no tiene un ide para compilar en c

    ReplyDelete
  15. Prueba netbeans, algunas cosas las e hecho con netbeans y me ha funcionado muy bien, y eso que netbeans es una plataforma de java pero con c/c++ funciona muy bien, aun así, trabajes con windows o linux o mac o lo que quieras, problemas vas a tener como yo y como cualquier persona.

    Busca por el error que te a salido en Google, seguro que encuentras alguien que habrá documentado dicho error.

    ReplyDelete
  16. Con cvLoadImage dices que podemos cargar imágenes en 3 canales (RGB), 1 canal (escala de grises), o lo que diga la cabecera del archivo.
    Si lo que quiero es mantener el canal alpha de una imagen con transparencia, como sería?

    ReplyDelete
  17. listo voy a provar con linux hay un distro llamado zenwalk que me parese prometedor tiene un ide para programar en c talves me sirva...estamos en contacto

    ReplyDelete
  18. No lo he probado pero como comento en el post con un valor -1 como argumento en la llamada de cvloadimage cogue los datos de la cabecera de la imagen con lo que un tga o png con canal alpha deberia aceptarlo correctamente.

    ReplyDelete
  19. parece que e podido resolver el problema de los programas con open cv al parecer eran las dll las cambien por otras bajadas de internet y listo...

    ReplyDelete
  20. Hola, como lei en uno de sus comentarios.... Ustedes usan Netbeans 6.5 con OpenCV.

    Tengo problemas con los settings del projecto. Alguien tiene un ejemplo de configuracion. ?

    Gracias.

    Tildes y acentos omitidos...

    ReplyDelete
  21. Hi
    I was going through the find_obj.cpp file given in the samples folder....but I didn't understand anything! Could you sometime write a tutorial on that...when you get the time...coz I found your OCR tutorial very helpful....thanks

    ReplyDelete
  22. Hola,
    Estoy realizando un proyecto con OpenCv y llevo un par de dias atascado con un problemilla, te lo expongo y a ver que piensas y si me podrias hechar una mano te estaria muy agradecido:

    Mi programa coge como entrada un video y lo va leyendo frame a frame, cada uno de estos frames lo convierte a escala de grises y realiza la substraccion de fondo:
    cvCvtColor(frame1, frame2, CV_BGR2GRAY);
    cvAbsDiff(primera,frame2,resta);
    cvThreshold(resta,binary,64,255,CV_THRESH_BINARY);

    Hasta aqui todo perfecto, pero paso a comprovar que la imagen almacenada en "binary" los unicos valores que contengan los pixeles sean 1s o 0s mediante el acceso directo a estos (almaceno el resultado en un fichero para poder comprobarlo despues):
    fs<<"a:"<imageData + binary->widthStep*50))[50]<<endl;

    He puesto 50 y 50 por acceder a un pixel aleatorio que se que va cambiando de valor.
    La sorpresa y mi mosqueo viene cuando abro el fichero para comprovar los datos y veo datos como:
    a:16777215
    a:-65536
    a:0
    a:0
    a:0
    a:0
    a:16777215
    a:-256
    a:0
    a:-65536
    a:-16777216
    a:16776960
    a:0
    a:0

    y la pregunta es¿no deberias ser todo 0s o 1s?

    ReplyDelete
  23. Como tu buen dices, deberia ser todo 0s y 1s o en su defecto 0 y 255, dependiendo si tienes la imagen creada tipo 8(char) o 32(float) para los 0s y 1s deberia ser 32

    ReplyDelete
  24. si la imagen la tengo creada tipo char, tienes idea de que puedo estar haciendo mal?


    en el post anterior habia una errata:fs<<”a:”widthStep*50))[50]<<endl;

    ReplyDelete
  25. puedes traducirme eso en un printf jajaja, nunca he echo uso de esa nonmenclatura, pero si pones widthStep*50 perfectamente te tiene que salir otra cosa.

    El acceso a los valores de pixel los tienes en http://blog.damiles.com/?p=25#comment-156

    ReplyDelete
  26. Saludos, me podrian ayudar o orientarme para poder usar el opencv... se los agradeceria

    ReplyDelete
  27. Te recomiendo que comiences por los ejemplos y documentación que aporta el código fuente de opencv, esto lo puedes encontrar en la carpeta opencv docs y carpeta samples/c o python dependiendo de en que lenguaje desees programar.

    ReplyDelete
  28. Ok, gracias, estoy trbajando con webcam, encontre un codigo bastante util, el cual me muestra la imagen original de la camara, en otra ventana un seleccion de colores, donde me muestra con mas intesidad la piel, y en una tercera ventna me muestra una segmentacion de la piel, lo que ando viendo es como hacer un adelgazamiento o eskeletizacion de esa segmentacion :S estoy trbadado, espero me ayuden o me orienten se los agradeceria

    ReplyDelete
  29. Para esas tareas te recomiendo que uses las funciones morfologicas:

    cvErode
    cvDilate
    cvMorphologyEx

    ReplyDelete
  30. Ok, eske soy nuevo en esto, pero pues a como me dice el maestro dice ke esta facil, nose si pueda contactade por medio de algo, te tengo en el skype. de vdd te lo agradeceria.. es un trbajo ke tengo para el 16 de junio pero no me gsuta dejar las cosasa amedia, aver si nos podemos de acuerdo sale saludos desde mexico

    ReplyDelete
  31. Holas.. amigo no mande nada eske se me paso decirte los fines de semana salgo fuera por cuestiones de trabajo. hoy lunes vemos ya sale, tengo unas sugerencias para ver cambios aver si te parece la idea. saludos

    ReplyDelete
  32. Hi,
    i am just a beginner with opencv and am not quite familiar with it, i need to process several images but i don't know how to load and display more than one image with opencv. i know how to use the cvloadimage function to load and display a pic. can u pls help me with a piece of code on how to load and process more than one image? thx in advance.

    ReplyDelete
  33. For load more than 1 image you can load it one by one or you can use a video (cvCreateFileCapture) with all frames and process each frame (cvQueryFrame). I think there are a function to load a image sequence as a video, but i'm not sure.

    ReplyDelete
  34. Hola buenas, tengo el mismo problema que comentaba mariano.
    Al quere ejecutar un ejemplo me salta:
    "no se ha podido inicializar correctamente (0xc0150002)"
    si alguien me puede aydar, Mariano me podiras decir quales són estas dll que dices que canviaste?

    ReplyDelete
  35. Gracias ya he resuelto mi problema. lo que pasava era que tenia instalado vs2008 i tambien se tiene que instalar un paquete:
    http://www.microsoft.com/downloads/details.aspx?familyid=200B2FD9-AE1A-4A14-984D-389C36F85647&displaylang=en

    el c++ 2005 redistributable

    ReplyDelete
  36. Hola yo tengo un problema al compilar con python y no se que hacer tengo instalado el python25 y al compilar los ejemplos que vienen en opencv me marca lo siguiente:
    Error al iniciar la aplicación porque no se encontró python26.dll ya le instale python26 pero me marca este error: Module use of python26.dll conflicts with this version of Python. Si alguien me puede ayudar se lo agradeceria.

    ReplyDelete
  37. Cesar, si te fijas de pide python26 es decir la version 2.6 y tu tienes la 2.5 instala la version de python 2.6 y no tendrás problemas.

    ReplyDelete
  38. si ya lo hice pero al instalarlo me marca este error Module use of python26.dll conflicts with this version of Python. y por eso le quite el python 26

    ReplyDelete
  39. Hi Sir,
    I'd like to merge several images into one single image (like accessing each image pixels value) ie create a new image containing all the features of the other images....but i don't know how to do so. pls can you be of any help? i'm using visual studio+opencv.
    Thanx in advance

    ReplyDelete
  40. Felipe Luiz CarnevaliOctober 27, 2009 at 4:41 PM

    Someone has something done or some link on the OpenCV in Delphi 7?

    ReplyDelete
  41. Hola sir,
    I want to use the features extraction on gait recognition. actually i have a silhouette and i want to know how to extract the features and then use it for recognize the same individual later . i am new in opencv and working with visual studio.
    Thank you

    ReplyDelete
  42. Hi,
    it's been a month since i posted a comment man, should i conclude that my question does not deserve an answer?

    ReplyDelete
  43. Hola, estoy empezando con openCV y la verdad que tengo idea de programacion en C pero nunca hasta ahora algo como esto.
    Quisiera hacer segmentacion de objetos en el video mediante sustraccion de fondo.
    Quisiera saber si es que alguien ya utilizo openCV con VS2005, porque ya van varios dias que estoy tratando de compilar y siempre tengo errores en la compilacion.
    Quisiera alguna sugerencia en todo caso de otro IDE en el cual alguien haya tenido buenas experiencias utilizando la libreria.

    ReplyDelete
  44. Vamos a ver, yo si he utilizado OpenCV con VStudio pero hace mucho tiempo, ahora mi editor favorito es vim, para mi es lo mejor... jejejeje.

    Te recomiendo visites http://opencv.willowgarage.com/wiki/VisualC%2B%2B para mas información sobre opencv en visualC++

    ReplyDelete
  45. Amigo damiles, te cuento que estoy usando devc++ que es el IDE con el que aprendi a programar. Tengo un problema, dentro de mi proyecto, ya inclui todas las cabeceras, ademas de todas las dll que trae la instalacion del OPENCV. Aun asi, cuando compilo me tira que todas las funciones como por ejemplo, IplImage, cvLoadImage, cvNamedWindow y todas las funciones coma las variables me los dice que no estan declaradas.
    No se como hacer para que mi proyecto reconozca a estas funciones.

    Este problema me sucede tratando de correr tu programa tutorial.

    Muchas gracias por la respuesta.

    ReplyDelete
  46. Olá amigos, eu instalei o visual c++ 2008 e o opencv 1.2 qd eu tento rodar algo nele aparece uma msg dizendo que o arquivo não pode ser exibido alguem sabe o pq?

    Obrigado

    ReplyDelete
  47. Hello sir,
    can we use opencv to reconstruct the image from the intensity coefficients.
    If yes please give an idea to proceed.

    ReplyDelete
  48. Buenas noches. Actualmente estoy desarrollando mi tesis en reconocimiento de piezas por medio de netbeans de java, Me gustaria saber si conoces la libreria para adjuntar a este software y como seria su uso. te agradezco

    ReplyDelete
  49. Hola. Tu intención es programar en java o en C/C++, OpenCV esta pensado para programar en c/c++ o python, se que existen algunas implementaciones de opencv sobre java, solo debes buscar en google y encontrarás librerías como por ejemplo http://code.google.com/p/nativelibs4java/wiki/OpenCV.

    De todas formas puedes programar en c/c++ sobre netbeans.

    Atentamente David.

    ReplyDelete
  50. Hola macuca, deberías depurar tu aplicación para detectar donde falla, parece ser que sea un problema de acceso a un puntero no inicializado debidamente. O sea el tipico segmentation fault.

    Atentament David.

    ReplyDelete
  51. Buenas tardes
    Necesito realizar una aplciacion con opencv utilizando Java para mi tesis, q es un sistemad e deteccion d epiezas industriales por color y forma.

    Necesito en java porq toda la aplicacion la he desarrollado sobre ese lenguaje y es un objetivo por alcanzar. Les agradezco si me pueden colaborar. Gracias

    ReplyDelete
  52. Hola buenas noches.
    En primer lugar gracias por el ejemplo damiles. Tengo un problema con un código similar. El programa compila y muestra la ventana, pero no carga la imágen, creo que no la encuentra. He utilizado la función cvAddSearchPath("path de mi carpeta"), para indicar donde se encuentra, pero nada. No se si es que tiene que estar en alguna carpeta del propio Visual Studio. Utilizo de todas formas un método diferente al tuyo para cargar la imagen:

    IplImage* hoja = cvLoadImage("tpl_a.bmp", 1);
    cvNamedWindow( "ventana",0 );
    cvShowImage( "ventana", hoja);

    No se cual puede ser el problema. Te agradecería algún consejo
    Saludos

    ReplyDelete
  53. Hola, según lo que me comentas, el código que me indicas está correcto. Solo deberías comprobar que el nombre de la imágen, sea el correcto, y esté en el mismo lugar que el ejecutable, en vc++ suele ser la carpeta debug o release que se crean al compilar el proyecto. Además comprueba que tu imágen que estas cargando en RGB sea realmente RGB y no escala de grises.

    Atentamente David.

    ReplyDelete
  54. damiles, estoy enterado de tu alto conocimiento en el área de OCR usando OpenCV y quisiera recibir algo de tu ayuda para programar un sistema de reconocimiento de caracteres usando CvANN_MLP para leer matrículas de vehículos. Podrías contactarme por algun medio o enviarme información sobre cómo programar el sistema en C++? Espero respuesta. Mil gracias.

    ReplyDelete
  55. Hola,

    estoy desarrollando una aplicación para la universidad politécnica de valencia.Quiero utilizar una tableta Acer Iconia Tab A100 8Gb XE.H6REN.001 con Android 3.0 Honeycomb. ¿Sabes si las camaras que lleva son compatibles con la librería OPENCV? ¿Existe algún sitio dónde mirar las compatibilidades de la cámara con opencv ? (En la web de opencv no indica camaras compatibles para móviles).

    Muchas Gracias

    ReplyDelete
  56. Hola Angel, veo que eres compañero de la upv ;).

    Te comento, no conozco concretamente como trabaja las cámaras android, al ser un sistema unix, si usa el driver v4l no vas a tener ningún problema usando opencv.

    No existe un listado de camaras que soporta opencv ya que opencv simplemente recoge las imagenes capturadas de los drivers genericos como puede ser v4l en caso de linux, en caso del osx quictime etc...

    De todas formas si necesitas concretar mucho los presets de la cámara te recomiendo que trabajes la interfaz de la camara de forma independiente a opencv y que recogas el vector de los datos de la imagen y pases a una estructura opencv.

    Atentamente David.

    ReplyDelete
  57. Voy a hablar con ACER a ver que me cuentan sobre las cámaras
    y probaré lo que me has dicho.

    Gracias.

    ReplyDelete
  58. Hola q tal, yo tengo un problema, compile todo opencv, mi SO es windows 7, pero al intentar correr un programa incluso los ejemplos me aparece un error, de esta aplicacion a dejado de funcionar y el boton de finalizar, no se porque me tiene loco ese error..
    agradeceria la ayuda =D...

    ReplyDelete
  59. Hola damiles que pena molestarte tengo un proyecto de tratamiento de imágenes de la u en donde debo leer un archivo dicom y luego hacer un filtro de borde y realmente estoy estancado me podrían ayudar con el código

    ReplyDelete