Opencv 用直线函数绘制直方图

Opencv 用直线函数绘制直方图,opencv,Opencv,因此,我一直在继续我的opencv学习,并且正在努力使用直方图函数。我清楚地理解calchist函数,我的代码一直工作到那里,我不理解它的绘图 我意识到我将使用line函数在两点之间画一条线,但给出的点坐标确实让我困惑 我遵循这里的在线教程:我也遵循OpenCV cookbook版本2 根据在线教程的线路计算在步骤7,如下所示: for( int i = 1; i < histSize; i++ ) { line( histImage, Point( bin_w*(i-1

因此,我一直在继续我的opencv学习,并且正在努力使用直方图函数。我清楚地理解calchist函数,我的代码一直工作到那里,我不理解它的绘图

我意识到我将使用line函数在两点之间画一条线,但给出的点坐标确实让我困惑

我遵循这里的在线教程:我也遵循OpenCV cookbook版本2

根据在线教程的线路计算在步骤7,如下所示:

 for( int i = 1; i < histSize; i++ )
  {
      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float>(i-1)) ) ,
                       Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ),
                       Scalar( 255, 0, 0), 2, 8, 0  );
      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) ,
                       Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ),
                       Scalar( 0, 255, 0), 2, 8, 0  );
      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) ,
                       Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ),
                       Scalar( 0, 0, 255), 2, 8, 0  );
  }
for(int i=1;i
老实说,我很难理解这一点,以及hist_h和hist_w的值,为什么选择512和400

因此,我查阅了我的书,发现同样的问题得到了解决:

// Compute histogram first
cv::MatND hist= getHistogram(image);
// Get min and max bin values
double maxVal=0;
double minVal=0;
cv::minMaxLoc(hist, &minVal, &maxVal, 0, 0);
// Image on which to display histogram
cv::Mat histImg(histSize[0], histSize[0], 
CV_8U,cv::Scalar(255));
// set highest point at 90% of nbins
int hpt = static_cast<int>(0.9*histSize[0]);
// Draw a vertical line for each bin 
for( int h = 0; h < histSize[0]; h++ ) {
float binVal = hist.at<float>(h);
int intensity = static_cast<int>(binVal*hpt/maxVal);
// This function draws a line between 2 points 
cv::line(histImg,cv::Point(h,histSize[0]),
cv::Point(h,histSize[0]-intensity),
cv::Scalar::all(0));
}
return histImg;
}
//首先计算直方图
cv::MatND hist=getHistogram(图像);
//获取最小和最大bin值
双maxVal=0;
双最小值=0;
cv::minMaxLoc(hist,&minVal,&maxVal,0,0);
//要在其上显示直方图的图像
cv::Mat histImg(histSize[0],histSize[0],
CV_8U,CV::标量(255));
//将最高点设置为NBIN的90%
int hpt=静态_铸造(0.9*histSize[0]);
//为每个箱子画一条垂直线
for(int h=0;h
这里第二个点的坐标是我不理解的。为什么它的强度是负的

这可能是一个非常愚蠢的问题,但很抱歉,我不明白这里给出的坐标。。我在谷歌上搜索了足够多的例子,但没有找到任何帮助来澄清这一点

所以我想问的是,有人能给我解释一下这两种方法中给出的坐标系吗。我真的很感激

多谢各位


另外,我还想在此指出,histsize=256是关于第二个代码示例的

在OpenCV中,坐标系从左上角开始。所以矩阵的条目0,0在左上角,0,(cols-1)在右上角,(行-1),0在左下角,以及(行-1),(cols-1)在右下角

人类期望直方图从图像的底部开始。要实现这一点,请对坐标求反,并从(行-1)开始,而不是从0开始。在您的示例中,
rows==histsize[0]

您的代码有一个bug:
坐标
…,histsize[0]
无效!矩阵行从
0
运行到
histsize[0]-1

谈论第二个代码示例

在OpenCV中,坐标系从左上角开始。所以矩阵的条目0,0在左上角,0,(cols-1)在右上角,(行-1),0在左下角,以及(行-1),(cols-1)在右下角

人类期望直方图从图像的底部开始。要实现这一点,请对坐标求反,并从(行-1)开始,而不是从0开始。在您的示例中,
rows==histsize[0]

您的代码有一个bug:
坐标
…,histsize[0]
无效!矩阵行从
0
运行到
histsize[0]-1

非常感谢您让我了解坐标系的工作方式。我真的认为它像往常一样从左下角开始。此外,我还将histsize更改为histsize[0]-1。但我认为代码不是从左上角开始计算行和列,而是给它需要绘制的点的坐标。但是仍然试图理解使用的代码,根据代码,第一个点是
(0255)
,第二个点是
(0255)
。我仍然不明白强度问题,为什么要减去它?类似地,第二个循环将给出坐标
(1255)
(1255-强度)
,其中强度基本上是h处直方图的实际值除以直方图的最大值。哦,见鬼,我又糊涂了=/非常感谢您让我了解坐标系的工作方式。我真的认为它像往常一样从左下角开始。此外,我还将histsize更改为histsize[0]-1。但我认为代码不是从左上角开始计算行和列,而是给它需要绘制的点的坐标。但是仍然试图理解使用的代码,根据代码,第一个点是
(0255)
,第二个点是
(0255)
。我仍然不明白强度问题,为什么要减去它?类似地,第二个循环将给出坐标
(1255)
(1255-强度)
,其中强度基本上是h处直方图的实际值除以直方图的最大值。哦,见鬼,我又糊涂了=/