图像相似度计算之直方图方法OpenCV实现
2017-02-09 11:45
597 查看
目标
本文档尝试解答如下问题:如何使用OpenCV函数 compareHist 产生一个表达两个直方图的相似度的数值。
如何使用不同的对比标准来对直方图进行比较。
原理
要比较两个直方图( and
),
首先必须要选择一个衡量直方图相似度的 对比标准 (
) 。
OpenCV 函数 compareHist 执行了具体的直方图对比的任务。该函数提供了4种对比标准来计算相似度:
Correlation ( CV_COMP_CORREL )
其中
是直方图中bin的数目。
Chi-Square ( CV_COMP_CHISQR )
Intersection ( CV_COMP_INTERSECT )
Bhattacharyya 距离( CV_COMP_BHATTACHARYYA )
源码
本程序做什么?装载一张 基准图像 和 两张 测试图像 进行对比。
产生一张取自 基准图像 下半部的图像。
将图像转换到HSV格式。
计算所有图像的H-S直方图,并归一化以便对比。
将 基准图像 直方图与 两张测试图像直方图,基准图像半身像直方图,以及基准图像本身的直方图分别作对比。
显示计算所得的直方图相似度数值。
下载代码: 点击 这里
代码一瞥:
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; /** @函数 main */ int main( int argc, char** argv ) { Mat src_base, hsv_base; Mat src_test1, hsv_test1; Mat src_test2, hsv_test2; Mat hsv_half_down; /// 装载三张背景环境不同的图像 if( argc < 4 ) { printf("** Error. Usage: ./compareHist_Demo <image_settings0> <image_setting1> <image_settings2>\n"); return -1; } src_base = imread( argv[1], 1 ); src_test1 = imread( argv[2], 1 ); src_test2 = imread( argv[3], 1 ); /// 转换到 HSV cvtColor( src_base, hsv_base, CV_BGR2HSV ); cvtColor( src_test1, hsv_test1, CV_BGR2HSV ); cvtColor( src_test2, hsv_test2, CV_BGR2HSV ); hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) ); /// 对hue通道使用30个bin,对saturatoin通道使用32个bin int h_bins = 50; int s_bins = 60; int histSize[] = { h_bins, s_bins }; // hue的取值范围从0到256, saturation取值范围从0到180 float h_ranges[] = { 0, 256 }; float s_ranges[] = { 0, 180 }; const float* ranges[] = { h_ranges, s_ranges }; // 使用第0和第1通道 int channels[] = { 0, 1 }; /// 直方图 MatND hist_base; MatND hist_half_down; MatND hist_test1; MatND hist_test2; /// 计算HSV图像的直方图 calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false ); normalize( hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat() ); calcHist( &hsv_half_down, 1, channels, Mat(), hist_half_down, 2, histSize, ranges, true, false ); normalize( hist_half_down, hist_half_down, 0, 1, NORM_MINMAX, -1, Mat() ); calcHist( &hsv_test1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false ); normalize( hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat() ); calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false ); normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() ); ///应用不同的直方图对比方法 for( int i = 0; i < 4; i++ ) { int compare_method = i; double base_base = compareHist( hist_base, hist_base, compare_method ); double base_half = compareHist( hist_base, hist_half_down, compare_method ); double base_test1 = compareHist( hist_base, hist_test1, compare_method ); double base_test2 = compareHist( hist_base, hist_test2, compare_method ); printf( " Method [%d] Perfect, Base-Half, Base-Test(1), Base-Test(2) : %f, %f, %f, %f \n", i, base_base, base_half , base_test1, base_test2 ); } printf( "Done \n" ); return 0; }
解释
声明储存基准图像和另外两张对比图像的矩阵( RGB 和 HSV )Mat src_base, hsv_base; Mat src_test1, hsv_test1; Mat src_test2, hsv_test2; Mat hsv_half_down;
装载基准图像(src_base) 和两张测试图像:
if( argc < 4 ) { printf("** Error. Usage: ./compareHist_Demo <image_settings0> <image_setting1> <image_settings2>\n"); return -1; } src_base = imread( argv[1], 1 ); src_test1 = imread( argv[2], 1 ); src_test2 = imread( argv[3], 1 );
将图像转化到HSV格式:
cvtColor( src_base, hsv_base, CV_BGR2HSV ); cvtColor( src_test1, hsv_test1, CV_BGR2HSV ); cvtColor( src_test2, hsv_test2, CV_BGR2HSV );
同时创建包含基准图像下半部的半身图像(HSV格式):
hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) );
初始化计算直方图需要的实参(bins, 范围,通道 H 和 S ).
int h_bins = 50; int s_bins = 32; int histSize[] = { h_bins, s_bins }; float h_ranges[] = { 0, 256 }; float s_ranges[] = { 0, 180 }; const float* ranges[] = { h_ranges, s_ranges }; int channels[] = { 0, 1 };
创建储存直方图的 MatND 实例:
MatND hist_base; MatND hist_half_down; MatND hist_test1; MatND hist_test2;
计算基准图像,两张测试图像,半身基准图像的直方图:
calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false ); normalize( hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat() ); calcHist( &hsv_half_down, 1, channels, Mat(), hist_half_down, 2, histSize, ranges, true, false ); normalize( hist_half_down, hist_half_down, 0, 1, NORM_MINMAX, -1, Mat() ); calcHist( &hsv_test1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false ); normalize( hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat() ); calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false ); normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() );
按顺序使用4种对比标准将基准图像(hist_base)的直方图与其余各直方图进行对比:
for( int i = 0; i < 4; i++ ) { int compare_method = i; double base_base = compareHist( hist_base, hist_base, compare_method ); double base_half = compareHist( hist_base, hist_half_down, compare_method ); double base_test1 = compareHist( hist_base, hist_test1, compare_method ); double base_test2 = compareHist( hist_base, hist_test2, compare_method ); printf( " Method [%d] Perfect, Base-Half, Base-Test(1), Base-Test(2) : %f, %f, %f, %f \n", i, base_base, base_half , base_test1, base_test2 ); }
结果
使用下列输入图像:我们应该会预料到当将基准图像直方图及其自身进行对比时会产生完美的匹配, 当与来源于同一样的背景环境的半身图对比时应该会有比较高的相似度, 当与来自不同亮度光照条件的其余两张测试图像对比时匹配度应该不是很好:
下面显示的是结果数值:
对比标准 | 基准 - 基准 | 基准 - 半身 | 基准 - 测试1 | 基准 - 测试2 |
---|---|---|---|---|
Correlation | 1.000000 | 0.930766 | 0.182073 | 0.120447 |
Chi-square | 0.000000 | 4.940466 | 21.184536 | 49.273437 |
Intersection | 24.391548 | 14.959809 | 3.889029 | 5.775088 |
Bhattacharyya | 0.000000 | 0.222609 | 0.646576 | 0.801869 |
相关文章推荐
- 图像相似度计算之直方图方法OpenCV实现
- 图像相似度计算之直方图方法OpenCV实现
- 图像相似度计算之直方图方法OpenCV实现
- 图像相似度计算之哈希值方法OpenCV实现
- 图像相似度计算之哈希值方法OpenCV实现
- 图像相似度计算之哈希值方法OpenCV实现
- 图像相似度计算之哈希值方法OpenCV实现
- opencv图像相似度的计算方法
- 计算图像直方图(OpenCV内置实现)
- opencv实现灰度图像的直方图点计算以及灰度直方图显示
- 计算图像直方图方法,纠正calcHist调用错误(OpenCV)
- opencv学习之(五)-直方图计算和绘制图像直方图
- opencv基于直方图实现图像检索匹配
- OpenCV2+入门系列(四):计算图像的直方图,平均灰度,灰度方差
- 余弦方法计算相似度算法实现
- OpenCV【4】---calcHist 计算图像的直方图
- 【图像处理】基于OpenCV底层实现的直方图匹配
- 字符串相似度计算的方法,使用SQL以及C#实现,本文非原创摘自网络(.NET SQL技术交流群入群206656202需注明博客园)
- 通过傅里叶变换方法求图像卷积-OpenCV实现
- OpenCV 计算图像一维直方图