opencv dibujando un histogtwig 2d

Me pregunto cómo trazar un histogtwig 2d de una Mat HSV en opencv c ++. Mi código actual que intenta mostrarlo falla miserablemente. He buscado cómo trazar histogtwigs y todos los que encontré fueron aquellos que los trazaron como histogtwigs independientes en 1d.

Aquí está mi salida actual con el número de hue bins siendo 30 y saturation bins siendo 32:

Aquí hay otra salida con el número de hue bins siendo 7 y saturation bins siendo 5:

Me gustaría que se pareciera más al resultado aquí

http://docs.opencv.org/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html

También noté que cada vez que hago cout << Hist.size me da 50×50. ¿Debo entender que solo significa que la primera dimensión de la matriz es de 250?

Además, ¿cómo se puede ordenar el histogtwig de la frecuencia de valores más alta a la más baja (o viceversa)? Ese es otro problema que estoy tratando de resolver.

Mi función actual es la siguiente.

void Perform_Hist(Mat& MeanShift, Mat& Pyramid_Result, Mat& BackProj){ Mat HSV, Hist; int histSize[] = {hbins, sbins}; int channels[] = {0, 1}; float hranges[] = {0, 180}; float sranges[] = {0, 256}; const float* ranges[] = {hranges, sranges}; cvtColor(MeanShift, HSV, CV_BGR2HSV); Mat PyrGray = Pyramid_Result.clone(); calcHist(&HSV, 1, channels, Mat(), Hist, 2, histSize, ranges, true, false); normalize(Hist, Hist, 0, 255, NORM_MINMAX, -1, Mat()); invert(Hist, Hist, 1); calcBackProject(&PyrGray, 1, channels, Hist, BackProj, ranges, 1, true); double maxVal = 0; minMaxLoc(Hist, 0, &maxVal, 0, 0); int scale = 10; Mat histImage = Mat::zeros(sbins*scale, hbins*10, CV_8UC3); for(int i = 1; i < hbins * sbins; i++){ line(histImage, Point(hbins*sbins*(i-1), sbins - cvRound(Hist.at(i-1))), Point(hbins*sbins*(i-1), sbins - cvRound(Hist.at(i))), Scalar(255,0,0), 2, 8, 0); } imshow (HISTOGRAM, histImage); } 

¿Quisiste decir algo como esto?

Histograma HSV como gráfico 3D

  • es el histogtwig HSV mostrado como gráfico 3D
  • V se ignora para llegar a 3D (de lo contrario, sería un gráfico 4D …)

en caso afirmativo, esta es la forma de hacerlo (no uso OpenCV, así que ajústelo a sus necesidades):

  1. convertir la imagen de origen a HSV
  2. computar el histogtwig ignorando el valor de V
    • todos los colores con el mismo H, S se consideran de un solo color sin importar lo que sea el V
    • puedes ignorar cualquier otro, pero el parámetro V parece ser la mejor opción
  3. dibujar el gráfico

    • primera dibuja una elipse con un color más oscuro (disco base HSV)
    • luego, para cada punto, tome el valor del histogtwig correspondiente y trace una línea vertical con un color más shiny. El tamaño de línea es proporcional al valor del histogtwig

Aquí está el código de C ++ con el que hice esto:

 picture pic0,pic1,pic2,zed; int his[65536]; DWORD w; int h,s,v,x,y,z,i,n; double r,a; color c; // compute histogram (ignore v) pic2=pic0; // copy input image pic0 to pic2 pic2.rgb2hsv(); // convert to HSV for (x=0;x<65536;x++) his[x]=0; // clear histogram for (y=0;y>1; // HSV base disc position centers on the bottom y=pic1.ys-100; a=2.0*M_PI*double(h)/256.0; // disc -> x,y r=double(s)/256.0; x+=120.0*r*cos(a); // elipse for 3D ilusion y+= 50.0*r*sin(a); z=-y; if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } x++; if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } y++; if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } x--; if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } y--; w=h+(s<<8); // get histogram index for this color i=((pic1.ys-150)*his[w])/n; c.db[picture::_v]=255; // histogram brighter for (;(i>0)&&(y>0);i--,y--) { if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } x++; if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } y++; if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } x--; if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } y--; } } pic1.hsv2rgb(); // convert to RGB to see correct colors 
  • la imagen de entrada es pic0 (rosa), la imagen de salida es pic1 (gráfico de histogtwig)
  • pic2 es el pic0 convertido a HSV para el cálculo del histogtwig
  • zed es el búfer Zed para visualización 3D que evita la clasificación Z …

Utilizo mi propia clase de imágenes para las imágenes, por lo que algunos miembros son:

  • xs,ys tamaño de la imagen en píxeles
  • p[y][x].dd es píxel en la posición (x, y) como tipo entero de 32 bits
  • clear(color) : borra toda la imagen
  • resize(xs,ys) – cambia el tamaño de la imagen a una nueva resolución
  • rgb2hsv() y hsv2rgb() … adivina qué hace 🙂

[edit1] tu histogtwig 2D

Parece que tienes un código de color en una matriz 2D. Un eje es H y el segundo es S Entonces, necesita calcular el valor H,S desde la dirección del arreglo. Si es lineal, entonces para HSV[i][j] :

  • H=h0+(h1-h0)*i/maxi
  • S=s0+(s1-s0)*j/maxj
  • o i,j invertido
  • h0,h1,s0,s1 son los rangos de color
  • maxi,maxj son el tamaño de la matriz

Como puedes ver, también descartas a V como yo, así que ahora tienes H,S para cada celda en el histogtwig 2D. Donde la probabilidad es el valor de la celda. Ahora, si desea dibujar una imagen, necesita saber cómo generarla (como un gráfico 2D, 3D, mapeo, …). Para gráfico 2D sin dibujar, dibuje un gráfico donde:

  • x=i+maj*i
  • y=HSV[i][j]
  • color=(H,S,V=200);

Si desea ordenarlo, simplemente calcule el eje x de manera diferente o bucle la matriz 2D en orden de ordenamiento y x simplemente incremente

[edit2] actualización de código y algunas imágenes

He reparado el código de C ++ anterior (signo de valor Z incorrecto, condición de búfer Z modificada y puntos más grandes para una salida más agradable). Sus colores de matriz 2D pueden ser como este:

Colores HS

Donde un eje / índice es H , el otro S y el Value son fijos (elijo 200). Si tus axises se intercambian, entonces solo refleja por y=x , creo …

La clasificación por color es realmente solo un orden en el que se seleccionan todos los colores de la matriz. por ejemplo:

 v=200; x=0; for (h=0;h<256;h++) for (s=0;s<256;s++,x++) { y=HSV[h][s]; // here draw line (x,0)->(x,y) by color hsv2rgb(h,s,v); } 

Esta es la forma incremental. Puede calcular x de H,S lugar para lograr una clasificación diferente o intercambiar los fors ( x++ debe estar en el bucle interno)

Si quieres un gráfico de histogtwig RGB, mira:

  • cómo trazar el histogtwig de color rgb de la imagen con el objective c
    Intereting Posts