我想知道如何在opencv c++中绘制HSV Mat的2d直方图。我当前尝试显示它的代码失败了。我四处寻找如何绘制直方图,而我发现的所有内容都是将它们绘制为独立的1d直方图。这是我当前的输出,其中色相箱数为30,饱和度箱数为32:这是另一个输出,其中色相箱数为7,饱和度箱数为5:我希望它看起来更像这里的结果 http://docs.opencv.org/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html我还注意到,每当执行c 另外,如何将直方图从最高值频率降低到最低值频率(反之亦然)?那是我要解决的另一个问题。我当前的功能如下。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<float>(i-1))), Point(hbins*sbins*(i-1), sbins - cvRound(Hist.at<float>(i))), Scalar(255,0,0), 2, 8, 0); } imshow (HISTOGRAM, histImage);} 最佳答案 您的意思是这样的吗? 它是HSV直方图,显示为3D图 V被忽略以获取3D(否则将是4D图形...) 如果是,那么这是怎么做(我不使用OpenCV,因此请根据您的需要进行调整):将源图像转换为HSV 忽略V值计算直方图不管V是什么,所有具有相同H,S的颜色都被视为单色您可以忽略其他任何参数,但V参数看起来是最佳选择 绘制图形首先用较深的颜色绘制椭圆(HSV基本光盘)然后为每个点获取相应的直方图值,并绘制具有更亮颜色的垂直线。行大小与直方图值成正比 这是我使用的C++代码: 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 pic2pic2.rgb2hsv(); // convert to HSVfor (x=0;x<65536;x++) his[x]=0; // clear histogramfor (y=0;y<pic2.ys;y++) // compute it for (x=0;x<pic2.xs;x++) { c=pic2.p[y][x]; h=c.db[picture::_h]; s=c.db[picture::_s]; w=h+(s<<8); // form 16 bit number from 24bit HSV color his[w]++; // update color usage count ... }for (n=0,x=0;x<65536;x++) if (n<his[x]) n=his[x]; // max probability// draw the colored HSV base plane and histogramzed =pic1; zed .clear(999); // zed buffer for 3D pic1.clear(0); // image of histogramfor (h=0;h<255;h++) for (s=0;s<255;s++) { c.db[picture::_h]=h; c.db[picture::_s]=s; c.db[picture::_v]=100; // HSV base darker c.db[picture::_a]=0; x=pic1.xs>>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输入图像为pic0(玫瑰),输出图像为pic1(直方图) pic2是转换为HSV以进行直方图计算的pic0 zed是3D显示的Zed缓冲区,可避免Z排序... 我将自己的图片类用于图片,因此一些成员是: xs,ys图像大小(以像素为单位) p[y][x].dd是(x,y)位置的像素,为32位整数类型 clear(color)-清除整个图像 resize(xs,ys)-将图像调整为新分辨率 rgb2hsv()和hsv2rgb() ...猜猜它是干什么的:) [edit1]您的2D直方图好像您已将颜色编码为2D数组。一个轴是H,第二个轴是S。因此,您需要根据数组地址计算H,S值。如果它是线性的,则为HSV[i][j]: H=h0+(h1-h0)*i/maxi S=s0+(s1-s0)*j/maxj 或i,j反转 h0,h1,s0,s1是的颜色范围 maxi,maxj是数组大小如您所见,您也像我一样丢弃了V,所以现在您在直方图2D数组中每个单元格都有H,S。概率是单元格值。现在,如果要绘制图像,则需要知道如何输出图像(作为2D图形,3D,映射等)。对于未排序的2D图,绘制图,其中: x=i+maj*i y=HSV[i][j] color=(H,S,V=200); 如果要对其进行排序,则只需以不同的方式计算x轴或按排序顺序循环2D数组,x只需递增 [edit2]更新代码和一些图像我已经修复了上面的C++代码(错误的Z值符号,更改了Z缓冲区条件,并添加了较大的点以获得更好的输出)。您的2D阵列颜色可以是这样的:其中一个轴/索引是H,另一个轴/索引是S和Value是固定的(我选择200)。如果你的轴被交换了,那就用y=x镜像它,我想...颜色排序实际上只是从数组中选择所有颜色的顺序。例如: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); }这是递增方式。您可以从x计算H,S来实现不同的排序或交换fors(x++必须在内部循环中)如果要使用RGB直方图,请参见: how to plot rgb color histogram of image with objective c关于opencv - opencv绘制2d直方图,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29266466/ 10-11 22:16