本次案例将为大家介绍直方图计算和直方图均衡化,直方图的计算非常有用,在很多场合下都可以用上,不仅仅是在图像的灰度值上,还可能是在图像的其他特征上;图像的均衡化在图像预处理时经常被用到,它可以增强对比度,使得像素强度分布范围更广。
直方图计算:
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
程序功能:
①输入一张图片,分解图像的三个通道,对三个通道进行直方图计算,并显示出来
②分解图像的三个通道,对三个通道进行直方图均衡,再合并三个通道,最后显示图像和直方图计算图像
#include "stdafx.h" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; Mat calchistcontrol(vector<Mat> rgb); void draw(Mat hist,int histSize,Mat histImage,int bin_w,int hist_h,int rgb); /** @函数 main */ int main( int argc, char** argv ) { Mat src, dst,rgb_merge,histImage,histImage1; /// 装载图像 src = imread("scenery2.jpg" , 1 ); imshow("source_image",src); if( !src.data ) { return -1; } /// 分割成3个单通道图像 ( R, G 和 B ) vector<Mat> rgb_planes; split( src, rgb_planes ); ///直方图计算 histImage=calchistcontrol(rgb_planes); ///三个通道直方图均衡化 vector<Mat> rgb_planes1; split(src,rgb_planes1); equalizeHist(rgb_planes1[0],rgb_planes1[0]); equalizeHist(rgb_planes1[1],rgb_planes1[1]); equalizeHist(rgb_planes1[2],rgb_planes1[2]); ///三个通道直方图均衡化后直方图计算 histImage1=calchistcontrol(rgb_planes1); ///合并三通道 merge(rgb_planes1,rgb_merge); /// 显示直方图 imshow("calcHist Demo", histImage ); imshow("calcHist Demo1",histImage1); imshow("rgb_merge",rgb_merge); waitKey(0); return 0; } Mat calchistcontrol(vector<Mat> rgb) { vector<Mat> rgb_planes; rgb_planes=rgb; /// 设定bin数目 int histSize = 255; /// 设定取值范围 ( R,G,B) ) float range[] = { 0, 255 } ; const float* histRange = { range }; bool uniform = true; bool accumulate = false; Mat r_hist, g_hist, b_hist; /// 计算直方图: calcHist( &rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate ); calcHist( &rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate ); calcHist( &rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate ); // 创建直方图画布 int hist_w = 400; int hist_h = 400; int bin_w = cvRound( (double) hist_w/histSize ); Mat histImage( hist_w, hist_h, CV_8UC3, Scalar( 0,0,0) ); /// 将直方图归一化到范围 [ 0, histImage.rows ] normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); /// 在直方图画布上画出直方图 draw(r_hist,histSize,histImage,bin_w,hist_h,1); draw(g_hist,histSize,histImage,bin_w,hist_h,2); draw(b_hist,histSize,histImage,bin_w,hist_h,3); return histImage; } void draw(Mat hist,int histSize,Mat histImage,int bin_w,int hist_h,int rgb) { Scalar a; switch(rgb) { case 1: a=Scalar(0,0,255);break; case 2: a=Scalar(0,255,0);break; case 3: a=Scalar(255,0,0);break; } int flag=1,first; for( int i = 0; i < histSize; i++ ) { if (flag==1) { if (cvRound(hist.at<float>(i)!=0)) { flag=2; first=i; } else { i++; } } else { if (cvRound(hist.at<float>(i)!=0)) { line( histImage, Point( bin_w*(first), hist_h - cvRound(hist.at<float>(first)) ) , Point( bin_w*(i), hist_h - cvRound(hist.at<float>(i)) ), a, 2, 8, 0 ); first=i; } else { i++; } } } }
图2、合并图像
图3、源图像直方图 图4、合并图像直方图
功能:计算图像 的直方图
结构:
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 )
hist.at<float>(i)表示第i个bin中所保存的统计数量
功能:灰度图象直方图均衡化
结构:
void equalizeHist(InputArray src, OutputArray dst)
dst:目标图像,和源图像有同样的size和type
操作:
①、计算src的直方图H
②、归一化直方图,使得H中bins的和为255;
③、计算直方图积分
④、采用H'作为查询表进行变换:
该方法归一化图像亮度和增强对比度。