openCV学习笔记十四:直方图的均衡化及对比

1.直方图均衡化——equalizeHist()
2.直方图对比——compareHist()
void cvEqualizeHist( const CvArr* src, CvArr* dst )
src
输入的 8-比特 单信道图像
dst
输出的图像与输入图像大小与数据类型相同

compareHist函数返回一个数值,相关性方法范围为0到1,1为最好匹配,卡方法和Bhattacharyya距离法是值为0最好,而交集法为值越大越好。

// A code block
var foo = 'bar';
#include <cv.h>
#include <highgui.h>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
///灰度图像直方图均衡化
 //1.灰度直方图均衡化 
 Mat srcImg = imread("06.png",CV_LOAD_IMAGE_GRAYSCALE);
 //直方图均衡化需为8位单通道图像 
 Mat dstImg; 
 equalizeHist(srcImg,dstImg); 
 imshow("srcImg",srcImg); 
 imshow("dstImg",dstImg);
 //2.画出源图srcImg和目标图像dstImg的直方图 
 //2.1计算直方图 
 int nimages = 1;//图像的个数 
 int channels = 0;//需要统计通道的索引 
 Mat mask = Mat(); 
 Mat histImg_src;//存放srcImg输出的直方图 
 Mat histImg_dst;//存放dstImg输出的直方图 
 int dims = 1;//需要计算的直方图的维度 
 int histSize = 256;//计算的直方图的分组数 
 float range[] = { 0, 256 };//表示直方图每一维度的取值范围[0,256)
 const float* ranges[] = { range };//参数形式需要,表示每一维度数值的取值范围 
 calcHist(&srcImg, nimages, &channels, mask, histImg_src, dims, &histSize, ranges);//计算srcImg直方图 
 calcHist(&dstImg, nimages, &channels, mask, histImg_dst, dims, &histSize, ranges);//计算dstImg直方图 
 //2.2绘制直方图 
 //2.2.1绘制srcImg的直方图 
 double minValue = 0; 
 double maxValue = 0; 
 minMaxLoc(histImg_src, &minValue, &maxValue);//得到计算出的直方图中的最小值和最大值
 int width = histSize;//定义绘制直方图的宽度,令其等于histSize 
 int height = 400;//定义绘制直方图的高度
 Mat histShow_src = Mat::zeros(Size(width, height), CV_8UC3);//宽为histSize,高为height
 for (int i = 0; i < histSize; i++)//遍历histImg 
 {  
 float binValue = histImg_src.at<float>(i);//得到histImg中每一分组的值  
  cout << "i: " << i << " ,binValue: " << binValue << endl;  
  float realValue = (binValue / maxValue)*height;//归一化数据,缩放到图像的height之内  
  cout << "i: " << i << " ,realValue: " << realValue << endl;  //用直线方法绘制直方图,注意两端点坐标的计算  
  line(histShow_src, Point(i, height - 1), Point(i, height - 1 - realValue), Scalar(255, 0, 0), 1);
  } 
 namedWindow("srcHist", CV_WINDOW_NORMAL); imshow("srcHist", histShow_src); //2.2.2绘制dstImg的直方图 
 double minValue_dst = 0; 
 double maxValue_dst = 0; 
 minMaxLoc(histImg_dst, &minValue_dst, &maxValue_dst);//得到计算出的直方图中的最小值和最大值
 Mat histShow_dst = Mat::zeros(Size(width, height), CV_8UC3);//宽为histSize,高为height 
 for (int i = 0; i < histSize; i++)//遍历histImg
 { 
 float binValue = histImg_dst.at<float>(i);//得到histImg中每一分组的值  
  cout << "i: " << i << " ,binValue: " << binValue << endl; 
  float realValue = (binValue / maxValue_dst)*height;//归一化数据,缩放到图像的height之内 
  cout << "i: " << i << " ,realValue: " << realValue << endl;  //用直线方法绘制直方图,注意两端点坐标的计算  
  line(histShow_dst, Point(i, height - 1), Point(i, height - 1 - realValue), Scalar(255, 0, 0), 1);
  }
 namedWindow("dstHist",CV_WINDOW_NORMAL);
 imshow("dstHist", histShow_dst); 
 waitKey(0);
 return 0;
 }

运行结果如下:
在这里插入图片描述
对比:

// A code block
var foo = 'bar';
#include <cv.h>
#include <highgui.h>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
 Mat srcImg1 = imread("A.PNG", CV_LOAD_IMAGE_COLOR);
 Mat srcImg2 = imread("B.PNG", CV_LOAD_IMAGE_COLOR); //1.计算srcImg1和srcImg2的直方图 
 int nimages = 1;//图像的个数 
 int channels = 0;//需要统计通道的索引 
 Mat mask = Mat(); Mat histImg1;//存放srcImg1输出的直方图 
 Mat histImg2;//存放srcImg2输出的直方图 
 int dims = 1;//需要计算的直方图的维度 
 int histSize = 256;//计算的直方图的分组数 
 float range[] = { 0, 256 };//表示直方图每一维度的取值范围[0,256) 
 const float* ranges[] = { range };//参数形式需要,表示每一维度数值的取值范围 
 calcHist(&srcImg1, nimages, &channels, mask, histImg1, dims, &histSize, ranges);//计算srcImg1直方图
 calcHist(&srcImg2, nimages, &channels, mask, histImg2, dims, &histSize, ranges);//计算srcImg2直方图
 //2.直方图对比,注意是依据两源图像所计算出的直方图进行相似度对比. 
 double num1 = compareHist(histImg1, histImg2, CV_COMP_CORREL);//相关性方法(值越大匹配度越高) 
 double num2 = compareHist(histImg1, histImg2, CV_COMP_CHISQR);//卡方测量法(值越小匹配度越高)
 double num3 = compareHist(histImg1, histImg2, CV_COMP_INTERSECT);//直方图相交法(值越大匹配度越高)
 double num4 = compareHist(histImg1, histImg2, CV_COMP_BHATTACHARYYA);//Bhattacharyya测量法(小)
 cout << "CV_COMP_CORREL(max_best): " << num1 << endl; 
 cout << "CV_COMP_CHISQR(min_best): " << num2 << endl;
 cout << "CV_COMP_INTERSECT(max_best): " << num3 << endl; 
 cout << "CV_COMP_BHATTACHARYYA(min_best): " << num4 << endl; 
 //3.绘制srcImg1和srcImg2的直方图 
 //3.1绘制srcImg1的直方图 
 double minValue = 0;
 double maxValue = 0; 
 minMaxLoc(histImg1, &minValue, &maxValue);//得到计算出的直方图中的最小值和最大值 
 int width = histSize;//定义绘制直方图的宽度,令其等于histSize 
 int height = 400;//定义绘制直方图的高度
 Mat histShow1 = Mat::zeros(Size(width, height), CV_8UC3);//宽为histSize,高为height
 for (int i = 0; i < histSize; i++)//遍历histImg 
 {  
 float binValue = histImg1.at<float>(i);//得到histImg中每一分组的值   
 float realValue = (binValue / maxValue)*height;//归一化数据,缩放到图像的height之内  
 //用直线方法绘制直方图,注意两端点坐标的计算 
 line(histShow1, Point(i, height - 1),Point(i, height - 1 - realValue), Scalar(255, 0, 0), 1); 
 } 
 namedWindow("srcHist1", CV_WINDOW_NORMAL);
 imshow("srcHist1", histShow1); //3.2绘制srcImg2的直方图 
 double minValue2 = 0; 
 double maxValue2 = 0; 
 minMaxLoc(histImg2, &minValue2, &maxValue2);//得到计算出的直方图中的最小值和最大值 
 Mat histShow2 = Mat::zeros(Size(width, height), CV_8UC3);//宽为histSize,高为height 
 for (int i = 0; i < histSize; i++)//遍历histImg 
 {  
  float binValue = histImg2.at<float>(i);//得到histImg中每一分组的值 
  float realValue = (binValue / maxValue2)*height;//归一化数据,缩放到图像的height之内
  //用直线方法绘制直方图,注意两端点坐标的计算  
  line(histShow2, Point(i, height - 1), Point(i, height - 1 - realValue), Scalar(255, 0, 0), 1); 
 } 
 namedWindow("srcHist2",CV_WINDOW_NORMAL); 
 imshow("srcHist2", histShow2);  
 namedWindow("srcImg1", CV_WINDOW_NORMAL);
 imshow("srcImg1", srcImg1); 
 namedWindow("srcImg2", CV_WINDOW_NORMAL); 
 imshow("srcImg2", srcImg2); 
 waitKey(0);
 return 0;
 }

运行结果如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值