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
#include <cstdlib> #include <iostream> #include <cv.h> #include <highgui.h> #include <stdio.h> #include <math.h> struct Tpixel { int b;//Cantidad de AZUL int g;//Cantidad de Verde int r;//Cantidad de rojo int i;//Coordenadas en i int j;//Coordenadas en j }; struct Timagen { Tpixel *pixels; int anchura; int altura; int numPixels; }; struct Tregion { Tpixel *pixels; int numPixels; int xe; int yn; int ys; int xw; float percent; }; struct Tregiones { Tregion *regiones; int numRegiones; }; uchar *data; int esColorParecido(Tpixel p1,Tpixel p2) { if (((p1.b==0)&&(p1.g==0)&&(p1.r==0)) |((p2.b==0)&&(p2.g==0)&&(p2.r==0))) return 0; else //printf("distancia:%f\n",(sqrt(pow(p1.b-p2.b,2)+pow(p1.g-p2.g,2)+pow(p1.r-p2.r,2)))); //return (40>=()) } int esAmarillo (int B,int G,int R) { return( (R>20)& (G<R) &(B<R*0.20) ); } int esAzul (int B,int G,int R) { return((B>80)&(R<B*0.50)&(G<B*0.50)); } int esNaranja (int B,int G,int R) { return((R>200)&(B<40)&(G<150)&(G>100)); } int esDeColor(int B,int G,int R) { return((R>20)&(G>20)&(B>20)); } int esNegro(int B,int G,int R) { return((R<15)&(G<15)&(B<15)); } int esRojo(int B,int G,int R) { return((R>80)&(B<R/2)&(G<R/2)); } int esVerde(int B,int G,int R) { return((G>80)&(B<G/2)&(R<G/2)); } int esBlanco (int B,int G,int R) { return((R>210)&(B>210)&(G>210)); } int copiaRegion(Tregion *region1,Tregion region2) { region1->numPixels=region2.numPixels; region1->xe=region2.xe; region1->yn=region2.yn; region1->ys=region2.ys; region1->xw=region2.xw; region1->percent=region2.percent; region1->pixels=region2.pixels; } int nuevaRegion( Tregion *regionNueva) { regionNueva->numPixels=0; regionNueva->xe=0; regionNueva->yn=0; regionNueva->ys=0; regionNueva->xw=0; regionNueva->percent=0.0; regionNueva->pixels=0;// } int encolaRegion(Tregion regionNueva,Tregiones *regiones) { if (regiones->numRegiones==0) { copiaRegion(®iones->regiones[regiones->numRegiones],regionNueva); regiones->numRegiones++; } else { regiones->regiones=(Tregion *) realloc(regiones->regiones,(regiones->numRegiones+1)*sizeof(struct Tregion)); copiaRegion(®iones->regiones[regiones->numRegiones],regionNueva); regiones->numRegiones++; } } int pintaPixel(Tpixel pixel) { } int nuevaImagen(Timagen *imagen,int altura,int anchura) { imagen->altura=altura; imagen->anchura=anchura; imagen->numPixels=0; } int copiaPixel(Tpixel *pixel1,Tpixel pixel2) { pixel1->b=pixel2.b; pixel1->g=pixel2.g; pixel1->r=pixel2.r; pixel1->i=pixel2.i; pixel1->j=pixel2.j; } int encolaPixelFoto(Tpixel pixelNuevo,Timagen *imagen) { if (imagen->numPixels==0) { copiaPixel(&imagen->pixels[imagen->numPixels],pixelNuevo); imagen->numPixels++; } else { copiaPixel(&imagen->pixels[imagen->numPixels],pixelNuevo); imagen->numPixels++; } } int encolaPixel(Tpixel pixelNuevo,Tregion *region) { if (region->numPixels==0) { copiaPixel(®ion->pixels[region->numPixels],pixelNuevo); region->xe=pixelNuevo.j; region->xw=pixelNuevo.j; region->yn=pixelNuevo.i; region->ys=pixelNuevo.i; region->numPixels++; } else { copiaPixel(®ion->pixels[region->numPixels],pixelNuevo); region->numPixels++; } } int pintaRegion(Tregion region) { } int nuevoPixel(Tpixel *pixel) { pixel->r=0; pixel->g=0; pixel->b=0; pixel->i=0; pixel->j=0; } int buscaPixel(Tpixel pixel,Tregion *region,int altura, int anchura,int anchura_fila,int canales) { Tpixel pixelAux; int id=0; if (pixel.i-1>=0) { encolaPixel(pixelAux,region); data[(pixel.i)*anchura_fila+(pixel.j)*canales+0]=0; data[(pixel.i)*anchura_fila+(pixel.j)*canales+1]=0; data[(pixel.i)*anchura_fila+(pixel.j)*canales+2]=0; pixelAux.b=(int)data[(pixel.i-1)*anchura_fila+(pixel.j)*canales+0]; pixelAux.g=(int)data[(pixel.i-1)*anchura_fila+(pixel.j)*canales+1]; pixelAux.r=(int)data[(pixel.i-1)*anchura_fila+(pixel.j)*canales+2]; pixelAux.i=pixel.i-1; pixelAux.j=pixel.j; //printf("color PixelAzul:%d,color PixelVerde:%d,color PixelRojo:%d\n",pixel.b,pixel.g,pixel.r); //printf("color pixelAuxAzul:%d,color pixelAuxVerde:%d,color pixelAuxRojo:%d\n",pixelAux.b,pixelAux.g,pixelAux.r); //system("PAUSE"); if (esColorParecido(pixel,pixelAux)) { buscaPixel(pixelAux,region,altura,anchura,anchura_fila,canales); } } if (pixel.j-1>=0) { pixelAux.b=(int)data[(pixel.i)*anchura_fila+(pixel.j-1)*canales+0]; pixelAux.g=(int)data[(pixel.i)*anchura_fila+(pixel.j-1)*canales+1]; pixelAux.r=(int)data[(pixel.i)*anchura_fila+(pixel.j-1)*canales+2]; pixelAux.i=pixel.i; pixelAux.j=pixel.j-1; if (esColorParecido(pixel,pixelAux)) { buscaPixel(pixelAux,region,altura,anchura,anchura_fila,canales); } } if (pixel.i +1<=altura) { pixelAux.b=(int)data[(pixel.i+1)*anchura_fila+(pixel.j)*canales+0]; pixelAux.g=(int)data[(pixel.i+1)*anchura_fila+(pixel.j)*canales+1]; pixelAux.r=(int)data[(pixel.i+1)*anchura_fila+(pixel.j)*canales+2]; pixelAux.i=pixel.i+1; pixelAux.j=pixel.j; if (esColorParecido(pixel,pixelAux)) { buscaPixel(pixelAux,region,altura,anchura,anchura_fila,canales); } } if (pixel.j+1<=anchura) { pixelAux.b=(int)data[(pixel.i)*anchura_fila+(pixel.j+1)*canales+0]; pixelAux.g=(int)data[(pixel.i)*anchura_fila+(pixel.j+1)*canales+1]; pixelAux.r=(int)data[(pixel.i)*anchura_fila+(pixel.j+1)*canales+2]; pixelAux.i=pixel.i; pixelAux.j=pixel.j+1; if (esColorParecido(pixel,pixelAux)) { buscaPixel(pixelAux,region,altura,anchura,anchura_fila,canales); } } } int llenaRegiones (Tregiones *regiones,int altura, int anchura,int anchura_fila,int canales) {int i,j; int numPixeles=0; Tregion regionAux; Tpixel pixelAux; nuevaRegion(®ionAux); nuevoPixel(&pixelAux); for (i=10;i<altura;i++) for(j=10;j<anchura;j++) { if((esVerde(data[i*anchura_fila+j*canales+0], data[i*anchura_fila+j*canales+1], data[i*anchura_fila+j*canales+2])) |(esAzul(data[i*anchura_fila+j*canales+0], data[i*anchura_fila+j*canales+1], data[i*anchura_fila+j*canales+2])) |(esRojo(data[i*anchura_fila+j*canales+0], data[i*anchura_fila+j*canales+1], data[i*anchura_fila+j*canales+2])) ) { nuevaRegion(®ionAux); pixelAux.b=(INT)data[i*anchura_fila+j*canales+0]; pixelAux.g=(INT)data[i*anchura_fila+j*canales+1]; pixelAux.r=(INT)data[i*anchura_fila+j*canales+2]; pixelAux.i=i; pixelAux.j=j; encolaPixel(pixelAux,®ionAux); data[(i)*anchura_fila+(j)*canales+0]=0; data[(i)*anchura_fila+(j)*canales+1]=0; data[(i)*anchura_fila+(j)*canales+2]=0; buscaPixel(pixelAux,®ionAux,altura,anchura,anchura_fila,canales); if (regionAux.numPixels>1000) encolaRegion(regionAux,regiones); printf("numero de pixeles en region %d:%d\n",regiones->numRegiones,regiones->regiones[regiones->numRegiones].numPixels); } } //printf("numpixeles:%d",numPixeles); } void PintaRectangulo(int x1,int y1,int x2, int y2, IplImage* img) { CvPoint pt1, pt2; pt1.x = x1-10; pt1.y = y1-10; pt2.x = x2+10; pt2.y = y2+10; cvRectangle( img, pt1 , pt2 , CV_RGB(0,0,255),15, 8, 0 ); //Dibujamos el rectangulo } int main(int argc, char *argv[]) { IplImage* img = 0; IplImage* img2 = 0; int altura,anchura,anchura_fila,canales; Tregiones bufferRegiones; bufferRegiones.numRegiones=0; int xCerca=10000; int xLejos=0; int yCerca=10000; int yLejos=0; Tregiones regiones; Tregion regionAux; int i; char name0[]="C:\\VC\\Practicas\\Cubo5.JPG"; img=cvLoadImage(name0,1); if(!img){ } altura = img->height; anchura = img->width; anchura_fila = img->widthStep; canales = img->nChannels; data =(uchar*) img->imageData; Timagen imagen; altura, anchura, canales); Tpixel pixelAux; nuevaImagen(&imagen,altura,anchura); img2=cvCloneImage(img); cvNamedWindow( "Cubo0", 2 ); cvNamedWindow( "Cubo1", 2 ); llenaRegiones(&bufferRegiones,altura,anchura,anchura_fila,canales); for (i=0;i<bufferRegiones.numRegiones;i++) pintaRegion(bufferRegiones.regiones[i]); } //PintaRectangulo(xCerca,yCerca,xLejos,yLejos,img2); //PintaRectangulo(2650,1125,3050,1600,img2); cvShowImage("Cubo0", img ); cvShowImage("Cubo1", img2 ); cvWaitKey(0); // se pulsa tecla para terminar cvDestroyAllWindows(); // destruimos todas las ventanas cvReleaseImage(&img); return EXIT_SUCCESS; }
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