直⽅图对⽐(两个直⽅图的相似性如何度量)本⽂档尝试解答如下问题:
如何使⽤OpenCV函数产⽣⼀个表达两个直⽅图的相似度的数值。
英语句子积累如何使⽤不同的对⽐标准来对直⽅图进⾏⽐较。
原理
要⽐较两个直⽅图( and ), ⾸先必须要选择⼀个衡量直⽅图相似度的对⽐标准 () 。
OpenCV 函数执⾏了具体的直⽅图对⽐的任务。该函数提供了4种对⽐标准来计算相似度:
1. Correlation ( CV_COMP_CORREL )
柴进绰号其中
是直⽅图中bin的数⽬。
2. Chi-Square ( CV_COMP_CHISQR )
3. Interction ( CV_COMP_INTERSECT )
4. 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_ba, hsv_ba;
Mat src_test1, hsv_test1;
Mat src_test2, hsv_test2;
Mat hsv_half_down;
/// 装载三张背景环境不同的图像
if( argc < 4 )
{ printf("** Error. Usage: ./compareHist_Demo <image_ttings0> <image_tting1> <image_ttings2>\n");
return -1;
}
src_ba = imread( argv[1], 1 );
src_test1 = imread( argv[2], 1 );
src_test2 = imread( argv[3], 1 );
/// 转换到 HSV
cvtColor( src_ba, hsv_ba, CV_BGR2HSV );
cvtColor( src_test1, hsv_test1, CV_BGR2HSV );
cvtColor( src_test2, hsv_test2, CV_BGR2HSV );
hsv_half_down = hsv_ba( Range( ws/2, ws - 1 ), Range( 0, ls - 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_ba;
MatND hist_half_down;
MatND hist_test1;
MatND hist_test2;
/// 计算HSV图像的直⽅图
calcHist( &hsv_ba, 1, channels, Mat(), hist_ba, 2, histSize, ranges, true, fal );
normalize( hist_ba, hist_ba, 0, 1, NORM_MINMAX, -1, Mat() );
calcHist( &hsv_half_down, 1, channels, Mat(), hist_half_down, 2, histSize, ranges, true, fal );
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, fal );
normalize( hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat() );
calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, fal );
normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() );
///应⽤不同的直⽅图对⽐⽅法
永不消逝的番号for( int i = 0; i < 4; i++ )
{ int compare_method = i;
double ba_ba = compareHist( hist_ba, hist_ba, compare_method );
double ba_half = compareHist( hist_ba, hist_half_down, compare_method );
double ba_test1 = compareHist( hist_ba, hist_test1, compare_method );
double ba_test2 = compareHist( hist_ba, hist_test2, compare_method );
printf( " Method [%d] Perfect, Ba-Half, Ba-Test(1), Ba-Test(2) : %f, %f, %f, %f \n", i, ba_ba, ba_half , ba_test1, ba_test2 ); }
printf( "Done \n" );
return 0;
}
解释
1. 声明储存基准图像和另外两张对⽐图像的矩阵( RGB 和 HSV )
Mat src_ba, hsv_ba;
Mat src_test1, hsv_test1;
Mat src_test2, hsv_test2;
Mat hsv_half_down;
2. 装载基准图像(src_ba) 和两张测试图像:
if( argc < 4 )
{ printf("** Error. Usage: ./compareHist_Demo <image_ttings0> <image_tting1> <image_ttings2>\n");
return -1;
}
src_ba = imread( argv[1], 1 );
src_test1 = imread( argv[2], 1 );
src_test2 = imread( argv[3], 1 );
3. 将图像转化到HSV格式:
cvtColor( src_ba, hsv_ba, CV_BGR2HSV );
cvtColor( src_test1, hsv_test1, CV_BGR2HSV );
cvtColor( src_test2, hsv_test2, CV_BGR2HSV );
4. 同时创建包含基准图像下半部的半⾝图像(HSV格式):
hsv_half_down = hsv_ba( Range( ws/2, ws - 1 ), Range( 0, ls - 1 ) );
5. 初始化计算直⽅图需要的实参(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 };
6. 创建储存直⽅图的 MatND 实例:
MatND hist_ba;关于禁毒的知识
MatND hist_half_down;
MatND hist_test1;
守宫吃什么MatND hist_test2;
7. 计算基准图像,两张测试图像,半⾝基准图像的直⽅图:
calcHist( &hsv_ba, 1, channels, Mat(), hist_ba, 2, histSize, ranges, true, fal );
normalize( hist_ba, hist_ba, 0, 1, NORM_MINMAX, -1, Mat() );
calcHist( &hsv_half_down, 1, channels, Mat(), hist_half_down, 2, histSize, ranges, true, fal );
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, fal );
normalize( hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat() );
calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, fal );
normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() );
8. 按顺序使⽤4种对⽐标准将基准图像(hist_ba)的直⽅图与其余各直⽅图进⾏对⽐:
for( int i = 0; i < 4; i++ )
{ int compare_method = i;
double ba_ba = compareHist( hist_ba, hist_ba, compare_method );
空调故障double ba_half = compareHist( hist_ba, hist_half_down, compare_method );
double ba_test1 = compareHist( hist_ba, hist_test1, compare_method );
double ba_test2 = compareHist( hist_ba, hist_test2, compare_method );
printf( " Method [%d] Perfect, Ba-Half, Ba-Test(1), Ba-Test(2) : %f, %f, %f, %f \n", i, ba_ba, ba_half , ba_test1, ba_test2 );
}
结果
1. 使⽤下列输⼊图像:
第⼀张为基准图像,其余两张为测试图像。同时我们会将基准图像与它⾃⾝及其半⾝图像进⾏对⽐。
2. 我们应该会预料到当将基准图像直⽅图及其⾃⾝进⾏对⽐时会产⽣完美的匹配,当与来源于同⼀样的背景环境的半⾝图对⽐时应该会
有⽐较⾼的相似度,当与来⾃不同亮度光照条件的其余两张测试图像对⽐时匹配度应该不是很好:
3. 下⾯显⽰的是结果数值:
对⽐标准基准 - 基准基准 - 半⾝基准 - 测试1基准 - 测试2
Correlation 1.0000000.9307660.1820730.120447
1986年属虎五行属什么
Chi-square0.000000 4.94046621.18453649.273437
Interction24.39154814.959809 3.889029 5.775088
Bhattacharyya0.0000000.2226090.6465760.801869
对于Correlation和Interction标准, 值越⼤相似度越⼤。因此可以看到对于采⽤这两个⽅法的对⽐,*基准 - 基准* 的对⽐结果值是最⼤的,⽽基准 - 半⾝的匹配则是第⼆好(跟我们预测的⼀致)。⽽另外两
种对⽐标准,则是结果越⼩相似度越⼤。我们可以观察到基准图像直⽅图与两张测试图像直⽅图的匹配是最差的,这再⼀次印证了我们的预测。