本次要记录的内容的是有关于图像直方图的一些操作:直方图均衡化、直方图比较。
Mat image_equalizeHist;
Mat image_equalizeHist_B;
Mat image_equalizeHist_G;
Mat image_equalizeHist_R;
vector<Mat>bgr;
split(image, bgr);
//Mat image_gray;
//cvtColor(image, image_gray, COLOR_BGR2GRAY);
equalizeHist(bgr[0], image_equalizeHist_B); //直方图均衡化只可以输入单通道图
equalizeHist(bgr[1], image_equalizeHist_G);
equalizeHist(bgr[2], image_equalizeHist_R);
//将RGB图像分离成三张单通道图分别均衡化后再合并
bgr[0] = image_equalizeHist_B.clone();
bgr[1] = image_equalizeHist_G.clone();
bgr[2] = image_equalizeHist_R.clone();
merge(bgr, image_equalizeHist);
imshow("image_equalizeHist", image_equalizeHist);
//imshow("image_gray", image_gray);
主要的API为equalizeHist()
,这个函数的作用就是将输入图像进行直方图均衡化操作后输出一幅新图像,要注意的是,这里的输入图像只可以输入单通道图像,所以我们对三通道图像进行直方图均衡化时,需要先将其分离成三幅单通道的图像,再分别进行处理,随后再将输出的三幅单通道图像合成起来,这才最终完成对三通道图像的直方图均衡化操作。如果是单通道的图像,就可以直接使用这个API来进行操作。实现效果如下图:
通过对比可以很明显的看出来,直方图均衡化后的图像的清晰度、对比度、图像质感都有所提高,所以直方图均衡化可以作为一种不错的图像增强手段。
Mat src;
src = imread("D:\\opencv_c++\\opencv_tutorial\\data\\dataset\\train_img\\0\\cat.9.jpg");
imshow("src", src);
cvtColor(src, src, COLOR_BGR2HSV);
Mat image_hsv;
cvtColor(image, image_hsv, COLOR_BGR2HSV);
int channels[2] = { 0,1 }; //内容相关性比较,仅对H,S两个通道进行比较,不考虑V通道
Mat hist;
Mat hist2;
int dim = 2;
int histSize[2] = { 180, 255 };
float range_h[2] = { 0, 180 };
float range_s[2] = { 0, 256 };
const float *histRange[2] = { range_h, range_s };
calcHist(&image_hsv, 1, channels, Mat(), hist, dim, histSize, histRange, true, false);
calcHist(&src, 1, channels, Mat(), hist2, dim, histSize, histRange, true, false);
//进行直方图比较前需要先进行归一化
normalize(hist, hist, 0, 1, NORM_MINMAX, -1, Mat());
normalize(hist2, hist2, 0, 1, NORM_MINMAX, -1, Mat());
double compare1 = compareHist(hist, hist2, HISTCMP_CORREL);
double compare2 = compareHist(hist, hist2, HISTCMP_CHISQR);
double compare3= compareHist(hist, hist2, HISTCMP_BHATTACHARYYA);
cout << "相关性比较" << compare1 << endl;
cout << "卡方比较" << compare2 << endl;
cout << "巴氏距离" << compare3 << endl;
同样计算出H和S通道的直方图,然后进行归一化,注意这一步很重要,因为不同通道的取值范围不一样,需要先归一化到[0, 1],然后就可以通过APIcompareHist()
进行直方图比较。
compareHist()
这个API需要三个参数,分别是:前两个参数是需要进行比较的两个图像直方图,第三个参数是进行直方图比较的方法,主要有三种可以选择的方法:
相关性比较(HISTCMP_CORREL)值越接近1,相关性越高;越接近0,相关性越低;
卡方比较(HISTCMP_CHISQR)值越小越接近,为0时相似度最高;
巴氏距离(HISTCMP_BHATTACHARYYA),完全匹配为 0,完全不匹配为1。
从比较效果上看,巴氏距离是效果最好的直方图相似度算法。下面是两张猫猫图的对比输出结果:
可能是这两只猫猫的毛色背景的差距太大了,所以放在一起比较的话输出结果就偏向于是不相似的,因为上面的比较是基于H和S两个通道的,不同颜色对对比结果的影响是比较大。
好的本次整理到此结束,下次再继续~
PS:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢!