学习OpenCV范例(十七)——直方图计算和均衡化

http://blog.csdn.net/chenjiazhou12/article/details/21930673

本次案例将为大家介绍直方图计算和直方图均衡化,直方图的计算非常有用,在很多场合下都可以用上,不仅仅是在图像的灰度值上,还可能是在图像的其他特征上;图像的均衡化在图像预处理时经常被用到,它可以增强对比度,使得像素强度分布范围更广。

1、原理

直方图计算:

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html#histogram-calculation

直方图均衡化:

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/histograms/histogram_equalization/histogram_equalization.html#histogram-equalization

学习OpenCV:

http://download.csdn.net/detail/chenjiazhou12/7083295

2、代码实现

程序功能:

①输入一张图片,分解图像的三个通道,对三个通道进行直方图计算,并显示出来

②分解图像的三个通道,对三个通道进行直方图均衡,再合并三个通道,最后显示图像和直方图计算图像

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include "stdafx.h"  
  2.   
  3. #include "opencv2/highgui/highgui.hpp"  
  4. #include "opencv2/imgproc/imgproc.hpp"  
  5. #include <iostream>  
  6. #include <stdio.h>  
  7.   
  8. using namespace std;  
  9. using namespace cv;  
  10.   
  11. Mat calchistcontrol(vector<Mat> rgb);  
  12. void draw(Mat hist,int histSize,Mat histImage,int bin_w,int hist_h,int rgb);  
  13. /** @函数 main */  
  14. int main( int argc, char** argv )  
  15. {  
  16.     Mat src, dst,rgb_merge,histImage,histImage1;  
  17.     /// 装载图像  
  18.     src = imread("scenery2.jpg" , 1 );  
  19.     imshow("source_image",src);  
  20.   
  21.     if( !src.data )  
  22.     { return -1; }  
  23.   
  24.     /// 分割成3个单通道图像 ( R, G 和 B )  
  25.     vector<Mat> rgb_planes;  
  26.     split( src, rgb_planes );  
  27.   
  28.     ///直方图计算  
  29.     histImage=calchistcontrol(rgb_planes);  
  30.   
  31.     ///三个通道直方图均衡化  
  32.     vector<Mat> rgb_planes1;  
  33.     split(src,rgb_planes1);  
  34.     equalizeHist(rgb_planes1[0],rgb_planes1[0]);  
  35.     equalizeHist(rgb_planes1[1],rgb_planes1[1]);  
  36.     equalizeHist(rgb_planes1[2],rgb_planes1[2]);  
  37.   
  38.     ///三个通道直方图均衡化后直方图计算  
  39.     histImage1=calchistcontrol(rgb_planes1);  
  40.   
  41.     ///合并三通道  
  42.     merge(rgb_planes1,rgb_merge);  
  43.   
  44.     /// 显示直方图  
  45.     imshow("calcHist Demo", histImage );  
  46.     imshow("calcHist Demo1",histImage1);  
  47.     imshow("rgb_merge",rgb_merge);  
  48.   
  49.     waitKey(0);  
  50.   
  51.     return 0;  
  52.   
  53. }  
  54. Mat calchistcontrol(vector<Mat> rgb)  
  55. {  
  56.   
  57.     vector<Mat> rgb_planes;  
  58.     rgb_planes=rgb;  
  59.     /// 设定bin数目  
  60.     int histSize = 255;  
  61.   
  62.     /// 设定取值范围 ( R,G,B) )  
  63.     float range[] = { 0, 255 } ;  
  64.     const float* histRange = { range };  
  65.   
  66.     bool uniform = truebool accumulate = false;  
  67.   
  68.     Mat r_hist, g_hist, b_hist;  
  69.   
  70.     /// 计算直方图:  
  71.     calcHist( &rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );  
  72.     calcHist( &rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate );  
  73.     calcHist( &rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate );  
  74.   
  75.     // 创建直方图画布  
  76.     int hist_w = 400; int hist_h = 400;  
  77.     int bin_w = cvRound( (double) hist_w/histSize );  
  78.   
  79.     Mat histImage( hist_w, hist_h, CV_8UC3, Scalar( 0,0,0) );  
  80.   
  81.     /// 将直方图归一化到范围 [ 0, histImage.rows ]  
  82.     normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );  
  83.     normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );  
  84.     normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );  
  85.   
  86.     /// 在直方图画布上画出直方图  
  87.     draw(r_hist,histSize,histImage,bin_w,hist_h,1);  
  88.     draw(g_hist,histSize,histImage,bin_w,hist_h,2);  
  89.     draw(b_hist,histSize,histImage,bin_w,hist_h,3);  
  90.     return histImage;  
  91. }  
  92. void draw(Mat hist,int histSize,Mat histImage,int bin_w,int hist_h,int rgb)  
  93. {  
  94.     Scalar a;  
  95.     switch(rgb)  
  96.     {  
  97.     case 1: a=Scalar(0,0,255);break;  
  98.     case 2: a=Scalar(0,255,0);break;  
  99.     case 3: a=Scalar(255,0,0);break;  
  100.     }  
  101.     int flag=1,first;  
  102.         forint i = 0; i < histSize; i++ )  
  103.     {    
  104.         if (flag==1)  
  105.     {  
  106.         if (cvRound(hist.at<float>(i)!=0))  
  107.         {  
  108.             flag=2;  
  109.             first=i;  
  110.         }  
  111.         else  
  112.         {  
  113.             i++;  
  114.         }  
  115.     }  
  116.         else  
  117.         {  
  118.             if (cvRound(hist.at<float>(i)!=0))  
  119.             {  
  120.             line( histImage, Point( bin_w*(first), hist_h - cvRound(hist.at<float>(first)) ) ,  
  121.                   Point( bin_w*(i), hist_h - cvRound(hist.at<float>(i)) ),  
  122.                   a, 2, 8, 0  );  
  123.             first=i;  
  124.             }  
  125.             else  
  126.             {  
  127.                 i++;  
  128.             }  
  129.         }  
  130.   
  131.     }  
  132. }  

3、运行结果


                                  图1、源图像


                                      图2、合并图像

  

        图3、源图像直方图                     图4、合并图像直方图

4、用到的类和函数

calcHist

功能:计算图像 的直方图

结构:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void calcHist(const Mat* arrays, int narrays, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=truebool accumulate=false )  

arrays :源图像集,他们都需要有同样的depth,CV_8U或者CV_32F,同样的size,可以有任意的通道数
narrays :输入图像的个数
channels :需要统计的通道 (dim)索引
mask :掩码( 0 表示忽略该像素), 如果未定义,则不使用掩码,如果不为null,则只有与mask非零元素对应的像素点会被包含在计算直方图当中。
hist :输出直方图数组,是一个 dims 维的数组
dims :直方图的维数
histSize :直方图的大小,即每个维度的bin数目
ranges:每个维度的取值范围
uniform 、accumulate: bin大小相同,清除直方图痕迹

hist.at<float>(i)表示第i个bin中所保存的统计数量

equalizeHist

功能:灰度图象直方图均衡化

结构:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void equalizeHist(InputArray src, OutputArray dst)  

src:源图像,8bit单通道图片

dst:目标图像,和源图像有同样的size和type

操作:

①、计算src的直方图H

②、归一化直方图,使得H中bins的和为255;

③、计算直方图积分

                               H'_i =  \sum _{0  \le j < i} H(j)

④、采用H'作为查询表进行变换:\texttt{dst}(x,y) = H'(\texttt{src}(x,y))

该方法归一化图像亮度和增强对比度。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值