opencv学习之路(20)、直方图应用
一、直方图均衡化--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 }