一、直方图均衡化--equalizeHist()
1 #include "opencv2/opencv.hpp"
2 using namespace cv;
3
4 void main()
5 {
6 Mat srcImg = imread("E://02.jpg", 0); //以灰度方式打开,需要输入单通道图像
7 imshow("src", srcImg);
8 Mat dstImg; //均衡化后的图像
9 equalizeHist(srcImg, dstImg);
10 imshow("dst", dstImg);
11
12 //绘制src直方图
13 MatND dstHist; //定义存储直方图变量
14 int dims = 1; //需要统计的特征数目(只统计灰度值)
15 float hranges[] = {0, 256}; //范围[0,256)注意是最大值加1
16 const float* ranges[] = {hranges};
17 int bins = 256;
18 int channels = 0;
19 calcHist(&srcImg, 1, &channels, Mat(), dstHist, dims, &bins, ranges);
20 int scale = 1;
21 Mat HistImg(bins * scale, bins*1, CV_8UC3, Scalar(0)); //定义直方图输出图像
22 double minValue = 0;
23 double maxValue = 0;
24 minMaxLoc(dstHist, &minValue, &maxValue, 0, 0);
25 int hpt = saturate_cast<int>(0.9*bins); //设置最大值并防止溢出
26 int j=0;
27 for(int i=0; i<256; i++)
28 {
29 float binValue = dstHist.at<float>(i);
30 int realValue = saturate_cast<int>(binValue*hpt/maxValue); //归一化数据
31 line(HistImg, Point(i*scale, bins-1), Point(i*scale, bins-realValue), Scalar(0, 255, 0), 1, 8);
32 }
33 imshow("src_hist", HistImg);
34
35 //绘制dst直方图
36 calcHist(&dstImg, 1, &channels, Mat(), dstHist, dims, &bins, ranges);
37 Mat HistImg2(bins * scale, bins*1, CV_8UC3, Scalar(0)); //定义直方图输出图像
38 for(int i=0; i<256; i++)
39 {
40 float binValue = dstHist.at<float>(i);
41 int realValue = saturate_cast<int>(binValue*hpt/maxValue); //归一化数据
42 line(HistImg2, Point(i*scale, bins-1), Point(i*scale, bins-realValue), Scalar(0, 255, 0), 1, 8);
43 }
44 imshow("dst_hist", HistImg2);
45
46 waitKey(0);
47 }
注意:红色部分为均衡化的主要代码
彩色图像直方图均衡化
1 #include "opencv2/opencv.hpp"
2 using namespace cv;
3
4 void main()
5 {
6 Mat src = imread("E://05.jpg");
7 imshow("src", src);
8
9 //分割通道
10 vector<Mat>channels;
11 split(src,channels);
12 Mat blue,green,red,dst;
13 blue=channels.at(0);
14 green=channels.at(1);
15 red=channels.at(2);
16 //分别对BGR通道做直方图均衡化
17 equalizeHist(blue,blue);
18 equalizeHist(green,green);
19 equalizeHist(red,red);
20 //合并通道
21 merge(channels,dst);
22 imshow("dst", dst);
23
24 waitKey(0);
25 }
二、直方图对比
1 #include "opencv2/opencv.hpp"
2 #include<iostream>
3 using namespace cv;
4 using namespace std;
5
6 void main()
7 {
8 Mat src1 = imread("E://a.jpg");
9 Mat src2 = imread("E://b.jpg");
10 imshow("src1", src1);
11 imshow("src2", src2);
12
13 MatND dstHist; //定义存储直方图变量
14 int dims = 1; //需要统计的特征数目(只统计灰度值)
15 float hranges[] = {0, 256}; //范围[0,256)注意是最大值加1
16 const float* ranges[] = {hranges};
17 int bins = 256;
18 int channels = 0;
19 calcHist(&src1, 1, &channels, Mat(), dstHist, dims, &bins, ranges);
20 int scale = 1;
21 Mat HistImg(bins * scale, bins*1, CV_8UC3, Scalar(0)); //定义直方图输出图像
22 double minValue = 0;
23 double maxValue = 0;
24 minMaxLoc(dstHist, &minValue, &maxValue, 0, 0);
25 int hpt = saturate_cast<int>(0.9*bins); //设置最大值并防止溢出
26 int j=0;
27 for(int i=0; i<256; i++)
28 {
29 float binValue = dstHist.at<float>(i);
30 int realValue = saturate_cast<int>(binValue*hpt/maxValue); //归一化数据
31 line(HistImg, Point(i*scale, bins-1), Point(i*scale, bins-realValue), Scalar(0, 255, 0), 1, 8);
32 }
33 imshow("src1_hist", HistImg);
34
35 MatND dstHist2; //定义存储直方图变量
36 calcHist(&src2, 1, &channels, Mat(), dstHist2, dims, &bins, ranges);
37 Mat HistImg2(bins * scale, bins*1, CV_8UC3, Scalar(0)); //定义直方图输出图像
38 minMaxLoc(dstHist2, &minValue, &maxValue, 0, 0);
39 for(int i=0; i<256; i++)
40 {
41 float binValue = dstHist2.at<float>(i);
42 int realValue = saturate_cast<int>(binValue*hpt/maxValue); //归一化数据
43 line(HistImg2, Point(i*scale, bins-1), Point(i*scale, bins-realValue), Scalar(0, 255, 0), 1, 8);
44 }
45 imshow("src2_hist", HistImg2);
46
47 double matchValue0 = compareHist(dstHist, dstHist2, CV_COMP_CORREL); //值越大相似度越高
48 double matchValue1 = compareHist(dstHist, dstHist2, CV_COMP_CHISQR); //值越小相似度越高
49 double matchValue2 = compareHist(dstHist, dstHist2, CV_COMP_INTERSECT); //值越大相似度越高
50 double matchValue3 = compareHist(dstHist, dstHist2, CV_COMP_BHATTACHARYYA); //值越小相似度越高
51
52 cout<<"matchValue0(max_best)="<<matchValue0<<endl;
53 cout<<"matchValue1(min_best)="<<matchValue1<<endl;
54 cout<<"matchValue2(max_best)="<<matchValue2<<endl;
55 cout<<"matchValue3(min_best)="<<matchValue3<<endl;
56
57 waitKey(0);
58 }
三、反向投影
1 #include "opencv2/opencv.hpp"
2 using namespace cv;
3
4 #define WINDOW_NAME "【原始图】"
5 Mat g_hueImage;
6 int g_bins = 30;//直方图组距
7
8 void on_BinChange(int, void* )
9 {
10 MatND hist;
11 int histSize = MAX( g_bins, 2 );
12 float hue_range[] = { 0, 180 };
13 const float* ranges = { hue_range };
14 calcHist( &g_hueImage, 1, 0, Mat(), hist, 1, &histSize, &ranges, true, false );
15 normalize( hist, hist, 0, 255, NORM_MINMAX, -1, Mat() );
16
17 MatND backproj;
18 calcBackProject( &g_hueImage, 1, 0, hist, backproj, &ranges, 1, true );
19 imshow( "反向投影图", backproj );
20
21 int w = 400; int h = 400;
22 int bin_w = cvRound( (double) w / histSize );
23 Mat histImg = Mat::zeros( w, h, CV_8UC3 );
24 for( int i = 0; i < g_bins; i ++ )
25 {
26 rectangle( histImg, Point( i*bin_w, h ), Point( (i+1)*bin_w, h - cvRound( hist.at<float>(i)*h/255.0 ) ), Scalar( 100, 123, 255 ), -1 );
27 }
28 imshow( "直方图", histImg );
29 }
30
31 void main()
32 {
33 Mat g_srcImage = imread( "E://1.jpg" );
34 Mat g_hsvImage;
35 resize(g_srcImage, g_srcImage, Size(g_srcImage.cols/4, g_srcImage.rows/4));//原图太大,进行缩放
36 cvtColor( g_srcImage, g_hsvImage, CV_BGR2HSV );
37
38 g_hueImage.create( g_hsvImage.size(), g_hsvImage.depth() );
39 int ch[ ] = { 0, 0 };
40 mixChannels( &g_hsvImage, 1, &g_hueImage, 1, ch, 1 );//从输入中拷贝某通道到输出中特定的通道
41
42 namedWindow( WINDOW_NAME , CV_WINDOW_AUTOSIZE );
43 createTrackbar("色调组距 ", WINDOW_NAME , &g_bins, 180, on_BinChange );
44 on_BinChange(0, 0);
45
46 imshow( WINDOW_NAME , g_srcImage );
47 waitKey(0);
48 }