• 直方图是对数据的统计,并将统计结果分布于一系列预定义的槽中。这里的数据不仅仅指的是灰度值,它可以是任何能有效描述图像特征的数据,比如图像梯度等等。

  • 假设有一个矩阵包含一张图像的信息 (灰度值 0-255),我们已经知道灰度值范围是0-255,假设有16个槽(bin),则有下面的划分:

  • 我们可以统计落入每个槽中像素的数目,并用直方图的形式显示出来。

  • 让我们再来了解一下直方图的一些具体细节:

    1. dims: 需要统计的特征的数目, 在上例中, dims = 1 因为我们仅仅统计了灰度值(灰度图像)。
    2. bins: 每个特征空间 子区段 的数目,在上例中, bins = 16
    3. range: 每个特征空间的取值范围,在上例中, range = [0,255]
  • 怎样去统计两个特征呢? 在这种情况下, 直方图就是3维的了,x轴和y轴分别代表一个特征, z轴是掉入 组合中的样本数目, 同样的方法适用于更高维的情形 (超过2维的很难用可视化的方式显示出来)。

下面是读取一副图像的灰度图,然后显示它的灰度值统计直方图的代码:

int main( int argc, char** argv )
{
Mat src, dst; /// 以单通道方式打开图像
src = imread( "../lenna.jpg", 0); if( !src.data )
{ return -1; } /// 设定bin数目
int histSize[1] = {255}; /// 设定取值范围 ( R,G,B) )
float range[] = { 0, 255 } ;
const float* histRange = { range }; bool uniform = true; bool accumulate = false; //结果直方图
Mat hist; calcHist( &src, 1, 0, Mat(), hist, 1, histSize, &histRange, uniform, accumulate ); // 创建直方图画布
int hist_w = 512;
int hist_h = 512;
//计算每个bin的像素宽度
int bin_w = cvRound( (double) hist_w/histSize[0] ); Mat histImage( hist_w, hist_h, CV_8UC3, Scalar( 0,0,0) ); /// 将直方图归一化到范围 [ 0, histImage.rows ]
normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); /// 在直方图画布上画出直方图,线宽为bin_w
for( int i = 0; i < histSize[0]; i++ )
{
line( histImage, Point( bin_w*(i), hist_h - cvRound(hist.at<float>(i)) ) ,
Point( bin_w*(i), hist_h),
Scalar( 0, 0, 255), bin_w, 8, 0 );
} /// 显示直方图
namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE );
imshow("calcHist Demo", histImage ); waitKey(0); return 0; }

OpenCV中的直方图计算函数,参数比较多,第一个参数是指向图像矩阵的指针,之所以是指针,是因为OpenCV中,可以统计多个图像的直方图,并把结果累加起来,我们的代码中只有一副图像,所以取&src。第二个参数就是指统计图像的数量,本程序中为1。第三个参数表示对某个通道进行直方图统计,我们读入的是灰度图,只有一个通道,所以值为0 。第四个参数是掩码。第五个参数是输出的直方图结果矩阵。第六个参数是直方图的维数。第七个参数是每个维度的取值范围,我们是单通道图像灰度值直方图,所以取值范围是[0 ,255],通常这个参数是个二维指针。

//计算直方图

//第二个参数1表示只对一副图像进行直方图处理

//第三个参数表示只处理channel 0,对多个channel的图像,可以选1,2等等。

//第四个参数Mat(),表示不使用掩码

//hist是直方图结果

//第六个参数1表示是1维直方图

//第七个参数,直方图bin的数目

//第八个参数是像素取值范围,第九个参数是各维取值范围相同,第十个参数是是否累加多副图像的统计结果,如果处理多个图像,需要这个参数。

calcHist( &src, 1, 0, Mat(), hist, 1, histSize, &histRange, uniform, accumulate );

程序执行后效果如下:

程序源代码:工程文件FirstOpenCV18

最新文章

  1. 对CVE-2014-6271 [破壳漏洞] 的一次不太深入的跟踪
  2. ios - runtime运行时应用---交换方法
  3. 记一次惨痛的线上bug
  4. sql-in/not in和exists/not exists的区别
  5. Android 判断是否联网 是否打开上网
  6. HDU1159 &amp;&amp; POJ1458:Common Subsequence(LCS)
  7. 为什么大多数培训机构还停留在只教ssh框架?
  8. Docker笔记三:基于LVS DR模式构建WEB服务集群
  9. 记录一次APP的转让流程
  10. Python 3.3.2 round函数并非&quot;四舍五入&quot;
  11. Vue-cli在webpack内使用雪碧图(响应式)
  12. C#字符串和ASCII码的转换
  13. table自适应大小,以及内容换行
  14. [转载]EXCEL绝对引用中$A$1、A$1、$A1三个的区别?
  15. 快速排序——JavaScript实现
  16. python定义函数时,形参前加*和**的意义
  17. Idea调试
  18. 洛谷P1244 青蛙过河 DP/思路
  19. 一次dns缓存引发的慘案
  20. 王者荣耀交流协会final发布中间产物

热门文章

  1. 洛谷P2525 Uim的情人节礼物&#183;其之壱 [康托展开]
  2. Spring 定时操作业务需求
  3. BZOJ.4919.[Lydsy1706月赛]大根堆(线段树合并/启发式合并)
  4. 写在OI退役后和高中毕业前的一些话
  5. EXECL中怎么中把换行符换成任意字符
  6. 为什么Android手机总是越用越慢?
  7. PYQT设计无边框窗体
  8. ZOJ 2970 Faster, Higher, Stronger
  9. CodeForces 128D Numbers 构造
  10. C#高级编程9-第2章 核心C#