直方图的比较函数为compareHist,函数返回值为两矩阵的相似程度,有4种不同的对比标准来对直方图进行比较:
– CV_COMP_CORRELCorrelation 相关系数,相同为1,相似度范围为[ 1, 0 )
– CV_COMP_CHISQRChi-Square 卡方,相同为0,相似度范围为[ 0, +inf )
– CV_COMP_INTERSECTIntersection 直方图交,数越大越相似,,相似度范围为[ 0, +inf )
– CV_COMP_BHATTACHARYYABhattacharyya distance 做常态分别比对的Bhattacharyya 距离,相同为0,,相似度范围为[ 0, +inf )
其他函数:
Mat::operator()
Mat Mat::operator()(Range rowRange, Range colRange) const
rowRange – Start and end row of the extracted submatrix. The upper boundary is not included. To select all the rows, use Range::all().
colRange – Start and end column of the extracted submatrix. The upper boundary is not included. To select all the columns, use Range::all().
程序代码及详细注释:
// 045 直方图对比.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>using namespace std;
using namespace cv;
int main( int argc, char** argv )
{
//储存基准图像和另外两张对比图像的矩阵( RGB 和 HSV )
Mat src_base, hsv_base;
Mat src_test1, hsv_test1;
Mat src_test2, hsv_test2;
Mat hsv_half_down;
/// 装载三张背景环境不同的图
src_base = imread( "hand_sample1.jpg" );
src_test1 = imread( "hand_sample2.jpg" );
src_test2 = imread( "hand_sample3.jpg");
/// 转换到 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 ) );
/// 对hue通道使用50个bin,对saturatoin通道使用60个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() );
//测试图像1的二维直方图
calcHist( &hsv_test1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false );
normalize( hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat() );
//测试图像2的二维直方图
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 );
cout<<"Method "<<i<<": Base_Base Base-Half Base-Test(1) Base-Test(2)"<<endl;
cout<<" "<<base_base<<" "<<base_half<<" "<<base_test1<<" "<<base_test2<<endl;
// printf( " Method [%d] Base_Base , 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;
}
运行结果: