Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: W0lFy en 3 Diciembre 2010, 20:52 pm



Título: Libreria OpenCV Deteccion de cubo de rubik en imagen
Publicado por: W0lFy en 3 Diciembre 2010, 20:52 pm
Hola gente, se me está planteando un problema, necesito hacer una practica para la universidad y no encuentro donde tengo el problema...
se rata de pasarle imagenes donde en algun lugar de la imagen existe un cubo de rubik en cualquier anguloy cualquier cara de color las cuales pueden ser (rojo,verde,azul... y creo que con estos colores valdria para la deteccion). se plantea el problema de la siguiente manera. Hay que hacer un algoritmo de crecimiento de regiones el cual se encarga de meter en una lista de regiones todas aquellas que encuentra un pixel coincidente con otro porque tienen el color parecido. Bueno les entrego mi codigo y me dicen que hago mal, creo que me quedo sin memoria, nuestro profesor dijo que teniamos que usar la STL por lo mismo, yo no la uso por que no se usarla . a ver si me pueden ayudar unpoquito enfocar por donde puedo ir. les dejo mi codigo:

Código
  1. #include <cstdlib>
  2. #include <iostream>
  3. #include <cv.h>
  4. #include <highgui.h>
  5. #include <stdio.h>
  6. #include <math.h>
  7.  
  8.  
  9.  
  10.  
  11. struct Tpixel
  12. {      
  13.       int b;//Cantidad de AZUL
  14.       int g;//Cantidad de Verde
  15.       int r;//Cantidad de rojo
  16.       int i;//Coordenadas en i
  17.       int j;//Coordenadas en j
  18.       };
  19.  
  20. struct Timagen
  21. {
  22.       Tpixel *pixels;
  23.       int anchura;
  24.       int altura;
  25.       int numPixels;
  26.       };
  27. struct Tregion
  28. {      
  29.       Tpixel *pixels;
  30.       int numPixels;
  31.       int xe;
  32.       int yn;
  33.       int ys;
  34.       int xw;
  35.       float percent;
  36.  
  37.       };
  38.  
  39. struct Tregiones
  40. {
  41.      Tregion *regiones;
  42.      int numRegiones;
  43.      };
  44. uchar *data;
  45. int esColorParecido(Tpixel p1,Tpixel p2)
  46. {
  47.    if (((p1.b==0)&&(p1.g==0)&&(p1.r==0))
  48.       |((p2.b==0)&&(p2.g==0)&&(p2.r==0)))
  49.       return 0;
  50.    else
  51.    //printf("distancia:%f\n",(sqrt(pow(p1.b-p2.b,2)+pow(p1.g-p2.g,2)+pow(p1.r-p2.r,2))));
  52.    return (7>sqrt(pow(p1.b-p2.b,2)+pow(p1.g-p2.g,2)+pow(p1.r-p2.r,2)));
  53.    //return (40>=())
  54. }
  55.  
  56. int esAmarillo (int B,int G,int R)
  57. {
  58.    return( (R>20)& (G<R) &(B<R*0.20)
  59.  
  60.           );
  61. }
  62. int esAzul (int B,int G,int R)
  63. {
  64.   return((B>80)&(R<B*0.50)&(G<B*0.50));
  65. }
  66.  
  67. int esNaranja (int B,int G,int R)
  68. {
  69.    return((R>200)&(B<40)&(G<150)&(G>100));
  70. }
  71. int esDeColor(int B,int G,int R)
  72. {
  73.    return((R>20)&(G>20)&(B>20));
  74. }
  75.  
  76. int esNegro(int B,int G,int R)
  77. {
  78.    return((R<15)&(G<15)&(B<15));
  79. }
  80. int esRojo(int B,int G,int R)
  81. {
  82.    return((R>80)&(B<R/2)&(G<R/2));
  83. }
  84. int esVerde(int B,int G,int R)
  85. {
  86.  return((G>80)&(B<G/2)&(R<G/2));
  87.  
  88. }
  89. int esBlanco (int B,int G,int R)
  90. {
  91.    return((R>210)&(B>210)&(G>210));
  92. }
  93. int copiaRegion(Tregion *region1,Tregion region2)
  94. {
  95.       region1->numPixels=region2.numPixels;
  96.       region1->xe=region2.xe;
  97.       region1->yn=region2.yn;
  98.       region1->ys=region2.ys;
  99.       region1->xw=region2.xw;
  100.       region1->percent=region2.percent;
  101.       region1->pixels=region2.pixels;
  102. }    
  103. int nuevaRegion(  Tregion *regionNueva)
  104. {
  105.    regionNueva->numPixels=0;
  106.       regionNueva->xe=0;
  107.       regionNueva->yn=0;
  108.       regionNueva->ys=0;
  109.       regionNueva->xw=0;
  110.       regionNueva->percent=0.0;
  111.       regionNueva->pixels=0;//
  112. }
  113. int encolaRegion(Tregion regionNueva,Tregiones *regiones)
  114. {
  115.  
  116.    if (regiones->numRegiones==0)
  117.       {
  118.           regiones->regiones = (Tregion *)malloc(sizeof(struct Tregion));
  119.           copiaRegion(&regiones->regiones[regiones->numRegiones],regionNueva);
  120.           regiones->numRegiones++;
  121.       }
  122.    else
  123.        {
  124.  
  125.         regiones->regiones=(Tregion *) realloc(regiones->regiones,(regiones->numRegiones+1)*sizeof(struct Tregion));
  126.         copiaRegion(&regiones->regiones[regiones->numRegiones],regionNueva);
  127.         regiones->numRegiones++;
  128.        }
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135. }
  136. int pintaPixel(Tpixel pixel)
  137. {
  138.      printf("Azul:%d\n",pixel.b);
  139.      printf("Verde:%d\n",pixel.g);
  140.      printf("Rojo:%d\n",pixel.r);
  141.      printf("Coordenada i:%d\n",pixel.i);
  142.      printf("Coordenada j:%d\n",pixel.j);
  143. }
  144. int nuevaImagen(Timagen *imagen,int altura,int anchura)
  145. {
  146. imagen->altura=altura;
  147. imagen->anchura=anchura;
  148. imagen->numPixels=0;
  149. }
  150. int copiaPixel(Tpixel *pixel1,Tpixel pixel2)
  151. {
  152.       pixel1->b=pixel2.b;
  153.       pixel1->g=pixel2.g;
  154.       pixel1->r=pixel2.r;
  155.       pixel1->i=pixel2.i;
  156.       pixel1->j=pixel2.j;
  157. }
  158. int encolaPixelFoto(Tpixel pixelNuevo,Timagen *imagen)
  159. {
  160.    if (imagen->numPixels==0)
  161.       {
  162.           imagen->pixels = (Tpixel *)malloc(sizeof(struct Tpixel));
  163.           copiaPixel(&imagen->pixels[imagen->numPixels],pixelNuevo);
  164.  
  165.           imagen->numPixels++;
  166.       }
  167.    else
  168.        {
  169.  
  170.         imagen->pixels=(Tpixel *) realloc(imagen->pixels,(imagen->numPixels+1)*sizeof(struct Tpixel));
  171.         copiaPixel(&imagen->pixels[imagen->numPixels],pixelNuevo);
  172.         imagen->numPixels++;
  173.        }
  174. }
  175. int encolaPixel(Tpixel pixelNuevo,Tregion *region)
  176. {
  177.     if (region->numPixels==0)
  178.       {
  179.           region->pixels = (Tpixel *)malloc(sizeof(Tpixel));
  180.           copiaPixel(&region->pixels[region->numPixels],pixelNuevo);
  181.           region->xe=pixelNuevo.j;      
  182.           region->xw=pixelNuevo.j;
  183.           region->yn=pixelNuevo.i;      
  184.           region->ys=pixelNuevo.i;
  185.           region->numPixels++;
  186.       }
  187.    else
  188.        {
  189.  
  190.         region->pixels=(Tpixel *) realloc(region->pixels,(region->numPixels+1)*sizeof(Tpixel));
  191.         copiaPixel(&region->pixels[region->numPixels],pixelNuevo);
  192.         region->numPixels++;
  193.        }
  194. }
  195.  
  196. int pintaRegion(Tregion region)
  197. {
  198. printf("numPixels:%d\n",region.numPixels);
  199. printf("XEste%d\n",region.xe);
  200. printf("YNorte:%d\n",region.yn);
  201. printf("YSur:%d\n",region.ys);
  202. printf("EOste:%d\n",region.xw);
  203. printf("Porciento de cuadrado:%f\n",region.percent);
  204.  
  205. }
  206. int nuevoPixel(Tpixel *pixel)
  207. {
  208.    pixel->r=0;    
  209.    pixel->g=0;
  210.    pixel->b=0;
  211.    pixel->i=0;
  212.    pixel->j=0;        
  213.  
  214. }
  215. int buscaPixel(Tpixel pixel,Tregion *region,int altura, int anchura,int anchura_fila,int canales)
  216. {
  217.    Tpixel pixelAux;
  218.    int id=0;
  219.  
  220.  
  221. if (pixel.i-1>=0)
  222. {
  223.    encolaPixel(pixelAux,region);              
  224.    data[(pixel.i)*anchura_fila+(pixel.j)*canales+0]=0;
  225.    data[(pixel.i)*anchura_fila+(pixel.j)*canales+1]=0;
  226.    data[(pixel.i)*anchura_fila+(pixel.j)*canales+2]=0;
  227.    pixelAux.b=(int)data[(pixel.i-1)*anchura_fila+(pixel.j)*canales+0];
  228.    pixelAux.g=(int)data[(pixel.i-1)*anchura_fila+(pixel.j)*canales+1];
  229.    pixelAux.r=(int)data[(pixel.i-1)*anchura_fila+(pixel.j)*canales+2];
  230.    pixelAux.i=pixel.i-1;
  231.    pixelAux.j=pixel.j;
  232.    //printf("color PixelAzul:%d,color PixelVerde:%d,color PixelRojo:%d\n",pixel.b,pixel.g,pixel.r);
  233.    //printf("color pixelAuxAzul:%d,color pixelAuxVerde:%d,color pixelAuxRojo:%d\n",pixelAux.b,pixelAux.g,pixelAux.r);
  234.    //system("PAUSE");
  235.    if (esColorParecido(pixel,pixelAux))
  236.     {
  237.        buscaPixel(pixelAux,region,altura,anchura,anchura_fila,canales);      
  238.     }                        
  239.  
  240. }
  241.  
  242. if (pixel.j-1>=0)
  243. {
  244.    pixelAux.b=(int)data[(pixel.i)*anchura_fila+(pixel.j-1)*canales+0];
  245.    pixelAux.g=(int)data[(pixel.i)*anchura_fila+(pixel.j-1)*canales+1];
  246.    pixelAux.r=(int)data[(pixel.i)*anchura_fila+(pixel.j-1)*canales+2];
  247.    pixelAux.i=pixel.i;
  248.    pixelAux.j=pixel.j-1;
  249.    if (esColorParecido(pixel,pixelAux))
  250.     {
  251.         buscaPixel(pixelAux,region,altura,anchura,anchura_fila,canales);                                  
  252.     }
  253. }
  254. if (pixel.i +1<=altura)
  255. {
  256.    pixelAux.b=(int)data[(pixel.i+1)*anchura_fila+(pixel.j)*canales+0];
  257.    pixelAux.g=(int)data[(pixel.i+1)*anchura_fila+(pixel.j)*canales+1];
  258.    pixelAux.r=(int)data[(pixel.i+1)*anchura_fila+(pixel.j)*canales+2];
  259.    pixelAux.i=pixel.i+1;
  260.    pixelAux.j=pixel.j;
  261.    if (esColorParecido(pixel,pixelAux))
  262.     {
  263.         buscaPixel(pixelAux,region,altura,anchura,anchura_fila,canales);      
  264.      }
  265. }
  266.  if (pixel.j+1<=anchura)
  267.  {
  268.    pixelAux.b=(int)data[(pixel.i)*anchura_fila+(pixel.j+1)*canales+0];
  269.    pixelAux.g=(int)data[(pixel.i)*anchura_fila+(pixel.j+1)*canales+1];
  270.    pixelAux.r=(int)data[(pixel.i)*anchura_fila+(pixel.j+1)*canales+2];
  271.    pixelAux.i=pixel.i;
  272.    pixelAux.j=pixel.j+1;
  273.    if (esColorParecido(pixel,pixelAux))
  274.     {
  275.          buscaPixel(pixelAux,region,altura,anchura,anchura_fila,canales);      
  276.  
  277.     }
  278. }
  279. }
  280. int llenaRegiones (Tregiones *regiones,int altura, int anchura,int anchura_fila,int canales)
  281. {int i,j;
  282. int numPixeles=0;
  283. Tregion regionAux;
  284. Tpixel pixelAux;
  285. nuevaRegion(&regionAux);
  286. nuevoPixel(&pixelAux);
  287.  
  288. for (i=10;i<altura;i++)
  289.  
  290.    for(j=10;j<anchura;j++)
  291.       {                
  292.            if((esVerde(data[i*anchura_fila+j*canales+0],
  293.                        data[i*anchura_fila+j*canales+1],
  294.                        data[i*anchura_fila+j*canales+2]))
  295.               |(esAzul(data[i*anchura_fila+j*canales+0],
  296.                        data[i*anchura_fila+j*canales+1],
  297.                        data[i*anchura_fila+j*canales+2]))
  298.               |(esRojo(data[i*anchura_fila+j*canales+0],
  299.                        data[i*anchura_fila+j*canales+1],
  300.                        data[i*anchura_fila+j*canales+2]))
  301.               )
  302.               {
  303.                      nuevaRegion(&regionAux);                        
  304.                      pixelAux.b=(INT)data[i*anchura_fila+j*canales+0];
  305.                      pixelAux.g=(INT)data[i*anchura_fila+j*canales+1];
  306.                      pixelAux.r=(INT)data[i*anchura_fila+j*canales+2];
  307.                      pixelAux.i=i;
  308.                      pixelAux.j=j;
  309.                      encolaPixel(pixelAux,&regionAux);
  310.                      data[(i)*anchura_fila+(j)*canales+0]=0;
  311.                      data[(i)*anchura_fila+(j)*canales+1]=0;
  312.                      data[(i)*anchura_fila+(j)*canales+2]=0;
  313.                      buscaPixel(pixelAux,&regionAux,altura,anchura,anchura_fila,canales);
  314.                      if (regionAux.numPixels>1000)
  315.                         encolaRegion(regionAux,regiones);
  316.                      printf("numero de pixeles en region %d:%d\n",regiones->numRegiones,regiones->regiones[regiones->numRegiones].numPixels);  
  317.                      system("PAUSE");
  318.  
  319.               }
  320.       }
  321.    //printf("numpixeles:%d",numPixeles);
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328. }
  329. void PintaRectangulo(int x1,int y1,int x2, int y2, IplImage* img)
  330. {
  331.     CvPoint pt1, pt2;
  332.     pt1.x = x1-10;
  333.     pt1.y = y1-10;
  334.     pt2.x = x2+10;
  335.     pt2.y = y2+10;
  336.  
  337. cvRectangle( img, pt1 , pt2 , CV_RGB(0,0,255),15, 8, 0 ); //Dibujamos el rectangulo
  338.  
  339.  
  340. }
  341.  
  342. int main(int argc, char *argv[])
  343. {
  344. IplImage* img = 0;
  345. IplImage* img2 = 0;
  346. int altura,anchura,anchura_fila,canales;
  347.  
  348.  
  349. Tregiones bufferRegiones;
  350. bufferRegiones.numRegiones=0;
  351. int xCerca=10000;
  352. int xLejos=0;
  353. int yCerca=10000;
  354. int yLejos=0;
  355. Tregiones regiones;
  356. Tregion regionAux;
  357. int i;
  358.  
  359.  
  360.  
  361. char name0[]="C:\\VC\\Practicas\\Cubo5.JPG";
  362.  
  363. img=cvLoadImage(name0,1);
  364.  
  365. if(!img){
  366.  printf("No se ha podido cargar la imagen: %s\n",argv[1]);
  367.  exit(0);
  368. }
  369.  
  370.  
  371.  
  372. altura    = img->height;
  373. anchura     = img->width;
  374. anchura_fila  = img->widthStep;
  375. canales  = img->nChannels;
  376. data   =(uchar*) img->imageData;
  377. Timagen imagen;
  378. printf("Procesando una imagen de %dx%d píxeles con %d canales\n",
  379.    altura, anchura, canales);
  380.    Tpixel pixelAux;
  381. nuevaImagen(&imagen,altura,anchura);
  382.  
  383. img2=cvCloneImage(img);
  384.  
  385. cvNamedWindow( "Cubo0", 2 );
  386. cvNamedWindow( "Cubo1", 2 );
  387. llenaRegiones(&bufferRegiones,altura,anchura,anchura_fila,canales);
  388. for (i=0;i<bufferRegiones.numRegiones;i++)
  389. {   printf("Numero Region:%d",i);
  390.    pintaRegion(bufferRegiones.regiones[i]);
  391. }
  392. //PintaRectangulo(xCerca,yCerca,xLejos,yLejos,img2);
  393. //PintaRectangulo(2650,1125,3050,1600,img2);
  394. printf("xCerca:%d\nyCerca:%d\nxLejos:%d\nyLejos:%d\n",xCerca,yCerca,xLejos,yLejos);
  395. cvShowImage("Cubo0", img );
  396. cvShowImage("Cubo1", img2 );
  397.  
  398. cvWaitKey(0); // se pulsa tecla para terminar
  399. cvDestroyAllWindows(); // destruimos todas las ventanas
  400. cvReleaseImage(&img);
  401.  
  402.    system("PAUSE");
  403.    return EXIT_SUCCESS;
  404. }
  405.  


Bueno pos cuando ejecuto el codigo, se ejecuta el programa y se cierra rapidamente. voy depurandolo, y es como si se quedara sin memoria. Lo que hago practicamente es:

- Busco en la imagen un pixel que sea rojo,azul o verde
- si lo encuentra... aplica el algoritmo de crecimiento de regiones que consiste en:
   *si el pixel de encima es de color parecido haz el algoritmo de busqueda en el y pinta de negro el pixel actual
  *si el pixel de la izquierda es de color parecido haz el algoritmo de busqueda en el y pinta de negro el pixel actual
   *si el pixel de abajo es de color parecido haz el algoritmo de busqueda en el y pinta de negro el pixel actual
   *si el pixel de la derecha es de color parecido haz el algoritmo de busqueda en el y pinta de negro el pixel actual

si acaba la llamada recursiva de buscapixel mete en el puntero de regiones una nueva region  ponte a buscar mas pixeles hasta que no haya mas pixeles rojos verdes y azules.

Si alguien pudiera ayudarme estaria totalmente agradecido.Se acepta todo tipo de criticas y comentarios. Un saludo