个人资料,仅供学习使用
修改时间——2022年2月14日 10:59:22
学习课程:OpenCV4 图像处理与视频分析实战教程
课程讲师:贾志刚

09 图像直方图+直方图均衡化+直方图比较

opencv知识点:

  • 计算直方图数据 - calcHist
  • 四舍五入浮点数 - cvRound
  • 寻找最小/最大值 - minMaxLoc
  • 均衡灰度图像的直方图 - equalizeHist
  • 比较直方图 - compareHist
  • 比较直方图的方法 - HistCompMethods

本课所解决的问题:

  • 什么是图像直方图?
  • 如何绘制彩色图像的一维直方图?
  • 如何绘制HSV图像的二维直方图?
  • 什么是图像直方图均衡化?
  • 如何均衡化灰度图像的直方图?
  • 如何均衡化彩色图像的直方图?
  • 什么是直方图比较?
  • 如何比较直方图?

1.图像直方图

直方图部分地方涉及了归一化,没有归一化基础可以阅读 18 图像像素类型转换与归一化,文章中非常详细。

关于图像直方图以及一维直方图的绘制,可以阅读 24 图像直方图,文章中非常详细。

关于二维直方图的绘制,可以阅读 25 二维直方图,文章中非常详细。

2.直方图均衡化

关于图像直方图的均衡化,可以阅读 26 直方图均衡化,文章中非常详细。

3.直方图比较

引用文章:

  • 【opencv学习笔记】026之直方图比较 - compareHist函数详解
  • opencv之直方图比较图像相似度

直方图比较的应用

当我们计算完两个图像的直方图后,可以对它们进行对比,并通过对比的结果得到一些结论。

比如

  • 图像相似度比较
    如果我们有两张图像,并且这两张图像的直方图一样,或者有极高的相似度,那么在一定程度上,我们可以认为这两幅图是一样的,这就是直方图比较的应用之一。

  • 分析图像之间关系
    两张图像的直方图反映了该图像像素的分布情况,可以利用直方图比较,来分析两张图像的关系。

直方图比较的方法

对输入的两张图像计算得到直方图H1与H2,并归一化到相同的尺度空间
然后可以通过计算H1与H2的之间的距离得到两个直方图的相似程度,进而比较图像本身的相似程度。

计算标准不同,则计算所得的相似程度不同。
我们称这个标准为衡量直方图相似度的对比标准(比较方法),这里设其为d(H1,H2)

常用的比较方法有四种:

  • 相关性比较(Correlation)——CV_COMP_CORREL
  • 卡方比较(Chi-Square)——CV_COMP_CHISQR
  • 十字交叉性(Intersection)——CV_COMP_INTERSECT
  • 巴氏距离(Bhattacharyya distance)——CV_COMP_BHATTACHARYYA

更多的比较方法可查阅OpenCV4官方文档

四种方法的原理

相关性比较
相关性比较的公式如下:

  • 如果H1 = H2,即两个图的直方图一样,分子等于分母,值为1,所以在不严格的情况下,当值为1时,可以认为两个图是一样的。

  • 但是也有可能会出现两个图不一样,而两个图的直方图是一样的情况。
    因为直方图计算的是像素点个数的分布情况,但是不会显示像素点的位置,所以有可能会出现两幅图片不一样,但是相同像素的个数完全一样,那他们的直方图也是一样的。
    不过这种情况,不常有。

相关性比较公式来源于统计学中的相关系数,一般用字母 r 表示。

其中,Cov(X,Y)为X与Y的协方差,sigma[X]为X的标准差,sigma[Y]为Y的标准差。r取值范围[-1,1]
相关系数适合数值与数值之间的关联性分析。
如果两个变量的相关性越强,相关系数就会越接近±1,相关性越弱,相关系数越接近0。

也就是说:

  • 相关性比较的值越趋近于0,相似度越低
  • 相关性比较的值越趋近于1,相似度越高

卡方比较
卡方比较的公式如下:

通过这个公式我们能够发现,卡方比较和相关性比较恰恰相反,

  • 卡方比较的值越趋近于1,相似度越低
  • 卡方比较的值越趋近于0,相似度越高

值为0时说明H1= H2,这个时候相似度最高。

卡方比较来源于卡方检验,卡方检验就是统计样本的实际观测值与理论推断值之间的偏离程度,
实际观测值与理论推断值之间的偏离程度就决定卡方值的大小,

  • 卡方值越大,越不符合
  • 卡方值越小,偏差越小,越趋于符合,
  • 若两个值完全相等时,卡方值就为0,表明理论值完全符合。

十字交叉性
十字交叉性的公式如下:

这个就比较简单了,对比H1,H2并求出最小值,最后求和。

巴氏距离
巴氏距离的公式如下:

在直方图相似度计算时,巴氏距离获得的效果最好,但计算是最为复杂的。

巴氏距离和相关性比较类似:

  • 巴氏距离的值越趋近于0,相似度越低
  • 巴氏距离的值越趋近于1,相似度越高

也就是说:巴氏距离的计算结果,其值完全匹配为1,完全不匹配则为0。

直方图比较演示

现在先介绍一下要用到的API

  • compareHist

compareHist

compareHist比较两个直方图共3个参数第1个参数 直方图H1第2个参数 直方图H2H1和H2大小要相同,要事先归一化第3个参数 比较方法(查阅官方文档可知)

比较之前, 一定要先对它们进行归一化处理,因为归一化后的比较才有意义。

本课中演示的直方图比较为BGR色彩空间,采取方式为

  • 计算图像的直方图,并归一化到[0~1]之间
  • 计算图1和图2、图1和图1相关性和巴氏距离

也可以用cvtColor()把图像从BGR转换到HSV等其他色彩空间,转换后其他地方一一对应即可

#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;void hist_compare() {Mat src1 = imread("D:/WorkSpace/Opencv/images/hahaha.jpg");Mat src2 = imread("D:/WorkSpace/Opencv/images/lena.png");imshow("input1", src1);imshow("input2", src2);int histSize[] = { 256, 256, 256 };int channels[] = { 0, 1, 2 };float c1[] = { 0, 255 };float c2[] = { 0, 255 };float c3[] = { 0, 255 };const float* histRanges[] = { c1, c2, c3 };Mat hist1, hist2;calcHist(&src1, 1, channels, Mat(), hist1, 3, histSize, histRanges, true, false);calcHist(&src2, 1, channels, Mat(), hist2, 3, histSize, histRanges, true, false);// 归一化normalize(hist1, hist1, 0, 1.0, NORM_MINMAX, -1, Mat());normalize(hist2, hist2, 0, 1.0, NORM_MINMAX, -1, Mat());// 相关性比较double c12 = compareHist(hist1, hist2, HISTCMP_CORREL);double c11 = compareHist(hist1, hist1, HISTCMP_CORREL);printf("c12 : %.2f, c11 : %.2f\n", c12, c11);// 比较巴氏距离double h12 = compareHist(hist1, hist2, HISTCMP_BHATTACHARYYA);double h11 = compareHist(hist1, hist1, HISTCMP_BHATTACHARYYA);printf("h12 : %.2f, h11 : %.2f\n", h12, h11);
}int main(int argc, char** argv) {//自写的函数hist_compare();waitKey(0);destroyAllWindows();return 0;
}

如图可知

  • 图1图2相关性比较:0.00;图1图1相关性比较:1.00
  • 图1图2卡方比较:1.00;图1图1卡方比较:0.00

本课所用API查阅

calcHist


#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
int main( int argc, char** argv )
{Mat src, hsv;if( argc != 2 || !(src=imread(argv[1], 1)).data )return -1;cvtColor(src, hsv, COLOR_BGR2HSV);// 将色调量化为 30 级// 饱和度为 32 级int hbins = 30, sbins = 32;int histSize[] = {hbins, sbins};// 色调从 0 到 179 变化,见 cvtColorfloat hranges[] = { 0, 180 };// 饱和度从 0(黑-灰-白)到// 255(纯光谱颜色)float sranges[] = { 0, 256 };const float* ranges[] = { hranges, sranges };MatND hist;// 我们从第 0 和第 1 通道计算直方图int channels[] = {0, 1};calcHist( &hsv, 1, channels, Mat(), // 不使用掩码hist, 2, histSize, ranges,true, // 直方图是统一的false );double maxVal=0;minMaxLoc(hist, 0, &maxVal, 0, 0);int scale = 10;Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3);for( int h = 0; h < hbins; h++ )for( int s = 0; s < sbins; s++ ){float binVal = hist.at<float>(h, s);int intensity = cvRound(binVal*255/maxVal);rectangle( histImg, Point(h*scale, s*scale),Point( (h+1)*scale - 1, (s+1)*scale - 1),Scalar::all(intensity),-1 );}namedWindow( "Source", 1 );imshow( "Source", src );namedWindow( "H-S Histogram", 1 );imshow( "H-S Histogram", histImg );waitKey();
}

cvRound



minMaxLoc




equalizeHist




merge


compareHist



HistCompMethods

【个人笔记】OpenCV4 C++ 图像处理与视频分析 09课相关推荐

  1. 【个人笔记】OpenCV4 C++ 图像处理与视频分析 12课

    个人资料,仅供学习使用 修改时间--2022年2月19日 14:57:51 学习课程:OpenCV4 图像处理与视频分析实战教程 课程讲师:贾志刚 12 图像模糊 opencv知识点: 高斯模糊 - ...

  2. 【个人笔记】OpenCV4 C++ 图像处理与视频分析 11课

    个人资料,仅供学习使用 修改时间--2022年2月19日 13:28:28 学习课程:OpenCV4 图像处理与视频分析实战教程 课程讲师:贾志刚 11 图像卷积+卷积边缘处理 opencv知识点: ...

  3. 【个人笔记】OpenCV4 C++ 图像处理与视频分析 10课

    个人资料,仅供学习使用 修改时间--2022年2月14日 10:59:22 学习课程:OpenCV4 图像处理与视频分析实战教程 课程讲师:贾志刚 10 图像查找表与颜色表 opencv知识点: 查找 ...

  4. 【个人笔记】OpenCV4 C++ 图像处理与视频分析 08课

    个人资料,仅供学习使用 修改时间--2022年2月13日 10:31:08 学习课程:OpenCV4 图像处理与视频分析实战教程 课程讲师:贾志刚 08 图像通道分离合并与混合 opencv知识点: ...

  5. 【个人笔记】OpenCV4 C++ 图像处理与视频分析 07课

    个人资料,仅供学习使用 修改时间--2022年2月13日 09:51:04 学习课程:OpenCV4 图像处理与视频分析实战教程 课程讲师:贾志刚 07 图形绘制与填充+文字绘制+随机绘制+矩形ROI ...

  6. 【个人笔记】OpenCV4 C++ 图像处理与视频分析 04课

    个人资料,仅供学习使用 修改时间--2022年2月10日 09:16:31 学习课程:OpenCV4 图像处理与视频分析实战教程 课程讲师:贾志刚 04 图像算术操作+调整亮度与对比度+伪装透明度 o ...

  7. 【个人笔记】OpenCV4 C++ 图像处理与视频分析 03课

    个人资料,仅供学习使用 修改时间--2022年2月7日 08:10:05 学习课程:OpenCV4 图像处理与视频分析实战教程 课程讲师:贾志刚 03 Mat 概念介绍+对象创建与赋值+像素读写 op ...

  8. 【个人笔记】OpenCV4 C++ 图像处理与视频分析 01课

    个人资料,仅供学习使用 修改时间--2022年2月5日 09:43:04 学习课程:OpenCV4 图像处理与视频分析实战教程 课程讲师:贾志刚 01 OpenCV4 框架介绍+环境搭建+显示图片 o ...

  9. 15 OpenCV4图像处理与视频分析实战(50.背景分析-)

    15 OpenCV4图像处理与视频分析实战(50.背景分析-) 一.50.背景分析- 来自网易云课堂(贾志刚) 一.50.背景分析- 大家我们就从中呢学会了一些东西,我们如果想把一些就是呃,更多的一些 ...

最新文章

  1. 没有找到合适的方法来重写_玻璃片价格太高?你可能没有找到合适的供应商
  2. python时间序列画图_简洁的Python时间序列可视化实现
  3. centos 删除crontab_centos7 定时任务crontab命令详解
  4. linux 查看强制位,linux强制位与冒险位
  5. Visual basic 6读写ini文件
  6. python内置作用域_python中的作用域
  7. qt显示rgba8888 如何改 frame_Qt开源作品17-IP地址输入控件
  8. 6还是5?大还是小?看完这些动图,感觉数学白学了
  9. java设置默认参数_关于java:如何设置默认方法参数值?
  10. linux中文显示和输入
  11. Java编程:贪心算法
  12. 驱动英特尔核显,让黑苹果流畅运行「OpenCore专门篇」
  13. Android设置屏幕亮度的两种方式
  14. Linux查看mpp数据库地址,linux下打开.mpp文件(微软project)._操作系统_rainysia的专栏-CSDN博客...
  15. the info.plist in the package must contain the CFBundleShortVersionString key.
  16. str.substring(0,str.length() -1)用法
  17. 用html和css构建简单的静态网页
  18. Android BootLoader及两种刷机模式fastboot和recovery
  19. 锁定“嵌入式AI”应用 中科创达启动第二轮成长
  20. Linux学习总结-Linux磁盘分区与挂载

热门文章

  1. pySpark | pySpark.Dataframe使用的坑 与 经历
  2. docker︱在nvidia-docker中使用tensorflow-gpu/jupyter
  3. 调整VirtualBox虚拟机分辨率的方法
  4. 由SELECT ... FROM ... FOR UPDATE想到的
  5. 《数字图像处理与机器视觉——Visual C++与Matlab实现》——0.2 数字图像处理与识别...
  6. C++三大特性之多态
  7. Linux命令行(console)屏幕分辨率调整
  8. mfc--使用ShellExecute打开另一个可执行程序
  9. 使用UTL_SMTP包发送邮件
  10. 30岁的我们还能做什么?