【转】OpenCV图像处理 图像的点运算 ( 灰度直方图 )

本文详细介绍了如何使用OpenCV库计算灰度图像的直方图,并通过示例代码展示了具体的实现过程。直方图是一种简单表格,记录了图像中各灰度级的像素数量。文中还解释了归一化直方图的概念及其计算方法。

 

 原文转自:http://ggicci.blog.163.com/blog/static/21036409620127591347744/
 

Title :

  • OpenCV灰度直方图

Theory :

从图形上看,灰度直方图是一个二维图:

gray_hist

图像的灰度直方图是一个离散函数,它表示图像每一灰度级与该灰度级出现频率的对应关系。假设一幅图像的像素总数为 N,灰度级总数为 L,其中灰度级为 g 的像素总数为 Ng,则这幅数字图像的灰度直方图横坐标即为灰度 g ( 0 ≤ g ≤ L-1 ),纵坐标则为灰度值出现的次数 Ng。实际上,用 N 去除各个灰度值出现的次数 Ng 即可得到各个灰度级出现的概率 Pg = Ng / N = Ng / ∑Ng ,从而得到归一化的灰度直方图,其纵坐标为概率 P

Quote : ( From [OpenCV 2 Computer Vision Application Programming Cookbook (Robert Langaniere, 2011) ], 引用作直方图的解释 )

  1. A histogram is a simple table that gives the number of pixels that have a given value in an image (or sometime a set of images). The histogram of a gray-level image will therefore have 256 entries (or bins).
  2. Histograms can also be normalized such that sum of the bins equals 1. In that case, each bin gives the percentage of pixels having this specific value in the image.

Implementation :

利用 OpenCV 提供的 calcHist 函数 :

void calcHist(const Mat* arrays, int narrays, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false );

这个函数用于计算直方图是很强大的,在这里就实现一个最简单的灰度图像的直方图计算。

Code :

   1: int main()
   2: {    
   3:     Mat img = imread("lena.jpg", CV_LOAD_IMAGE_GRAYSCALE);
   4: 
   5:     Mat* arrays = &img;
   6:     int narrays = 1;
   7:     int channels[] = { 0 };
   8:     InputArray mask = noArray();
   9:     Mat hist;
  10:     int dims = 1;
  11:     int histSize[] = { 256 };    
  12:     float hranges[] = { 0.0, 255.0 };
  13:     const float *ranges[] = { hranges };
  14:     //调用 calcHist 计算直方图, 结果存放在 hist 中
  15:     calcHist(arrays, narrays, channels, mask, hist, dims, histSize, ranges);
  16:     
  17:     //调用一个我自己写的简单的函数用于获取一张显示直方图数据的图片,
  18:     //输入参数为直方图数据 hist 和期望得到的图片的尺寸
  19:     Mat histImg = ggicci::getHistogram1DImage(hist, Size(600, 420));
  20:     imshow("lena gray image histogram", histImg);
  21:     waitKey();
  22: }
  23: 
  24: Mat ggicci::getHistogram1DImage(const Mat& hist, Size imgSize)
  25: {
  26:     Mat histImg(imgSize, CV_8UC3);
  27:     int Padding = 10;
  28:     int W = imgSize.width - 2 * Padding;
  29:     int H = imgSize.height - 2 * Padding;
  30:     double _max;
  31:     minMaxLoc(hist, NULL, &_max);
  32:     double Per = (double)H / _max;
  33:     const Point Orig(Padding, imgSize.height-Padding);
  34:     int bin = W / (hist.rows + 2);
  35: 
  36:     //画方柱
  37:     for (int i = 1; i <= hist.rows; i++)
  38:     {
  39:         Point pBottom(Orig.x + i * bin, Orig.y);
  40:         Point pTop(pBottom.x, pBottom.y - Per * hist.at<float>(i-1));
  41:         line(histImg, pBottom, pTop, Scalar(255, 0, 0), bin);
  42:     }
  43: 
  44:     //画 3 条红线标明区域
  45:     line(histImg, Point(Orig.x + bin, Orig.y - H), Point(Orig.x + hist.rows *  bin, Orig.y - H), Scalar(0, 0, 255), 1);
  46:     line(histImg, Point(Orig.x + bin, Orig.y), Point(Orig.x + bin, Orig.y - H), Scalar(0, 0, 255), 1);
  47:     line(histImg, Point(Orig.x + hist.rows * bin, Orig.y), Point(Orig.x + hist.rows *  bin, Orig.y - H), Scalar(0, 0, 255), 1);
  48:     drawArrow(histImg, Orig, Orig+Point(W, 0), 10, 30, Scalar::all(0), 2);
  49:     drawArrow(histImg, Orig, Orig-Point(0, H), 10, 30, Scalar::all(0), 2);
  50:     
  51:     return histImg;
  52: }

Result :

lenaimage

airplaneimage


End :

Author : Ggicci

欢迎阅读, 如有错误, 希望指正!

--OpenCV 初学者

转载于:https://www.cnblogs.com/mlv5/archive/2013/02/03/2890897.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值