也是直方图匹配的一种形式
函数原型:
CVAPI(float) cvCalcEMD2( const CvArr* signature1,
const CvArr* signature2,
int distance_type,
CvDistanceFunction distance_func CV_DEFAULT(NULL),
const CvArr* cost_matrix CV_DEFAULT(NULL),
CvArr* flow CV_DEFAULT(NULL),
float* lower_bound CV_DEFAULT(NULL),
void* userdata CV_DEFAULT(NULL));
可以轻量化地调用这个函数:
CVAPI(float) cvCalcEMD2( const CvArr* signature1,
const CvArr* signature2,
int distance_type);
需要将图像先转换成两个矩阵再进行匹配对比
测试图像(骨灰级找茬图像):
程序代码:
#include <highgui.h>
#include<cv.h>
#include <opencv2/legacy/legacy.hpp>
using namespace std;
int main()
{
IplImage *src1 = cvLoadImage("test1.jpg");
IplImage *b_plane_1 = cvCreateImage(cvGetSize(src1),8,1);
IplImage *g_plane_1 = cvCreateImage(cvGetSize(src1),8,1);
IplImage *r_plane_1 = cvCreateImage(cvGetSize(src1),8,1);
IplImage *planes1[]={b_plane_1,g_plane_1,r_plane_1};
cvSplit(src1,b_plane_1,g_plane_1,r_plane_1,0);
cvNamedWindow("src1",CV_WINDOW_AUTOSIZE);
cvShowImage("src1",src1);
IplImage *src2 = cvLoadImage("test2.jpg");
IplImage *b_plane_2 = cvCreateImage(cvGetSize(src2),8,1);
IplImage *g_plane_2 = cvCreateImage(cvGetSize(src2),8,1);
IplImage *r_plane_2 = cvCreateImage(cvGetSize(src2),8,1);
IplImage *planes2[]={b_plane_2,g_plane_2,r_plane_2};
cvSplit(src2,b_plane_2,g_plane_2,r_plane_2,0);
cvNamedWindow("src2",CV_WINDOW_AUTOSIZE);
cvShowImage("src2",src2);
int h_bins=16,s_bins=16;
CvHistogram *hist1,*hist2;
int size[]={h_bins,s_bins};
float h_ranges[]={0,255};
float s_ranges[]={0,255};
float *ranges[]={h_ranges,s_ranges};
hist1=cvCreateHist(2,size,CV_HIST_ARRAY,ranges,1);
cvCalcHist(planes1,hist1,0,0);
cvNormalizeHist(hist1,1.0);//归一化
hist2=cvCreateHist(2,size,CV_HIST_ARRAY,ranges,1);
cvCalcHist(planes2,hist2,0,0);
cvNormalizeHist(hist2,1.0);//归一化
CvMat *sig1,*sig2;
int numrows=h_bins*s_bins;
sig1=cvCreateMat(numrows,3,CV_32FC1);
sig2=cvCreateMat(numrows,3,CV_32FC1);
for(int h=0;h<h_bins;h++)
{
for(int s=0;s<s_bins;s++)
{
float bin_val=cvQueryHistValue_2D(hist1,h,s);
cvSet2D(sig1,h*s_bins+s,0,cvScalar(bin_val));
cvSet2D(sig1,h*s_bins+s,1,cvScalar(h));
cvSet2D(sig1,h*s_bins+s,2,cvScalar(s));
bin_val=cvQueryHistValue_2D(hist2,h,s);
cvSet2D(sig2,h*s_bins+s,0,cvScalar(bin_val));
cvSet2D(sig2,h*s_bins+s,1,cvScalar(h));
cvSet2D(sig2,h*s_bins+s,2,cvScalar(s));
}
}
printf("EMD : %.4f\n",cvCalcEMD2(sig1,sig2,CV_DIST_L2));
printf("CV_COMP_BHATTACHARYYA : %.4f\n",cvCompareHist(hist1,hist2,CV_COMP_BHATTACHARYYA));
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&src1); cvReleaseImage(&src2);
cvReleaseImage(&b_plane_1); cvReleaseImage(&g_plane_1); cvReleaseImage(&r_plane_1);
cvReleaseImage(&b_plane_2); cvReleaseImage(&g_plane_2); cvReleaseImage(&r_plane_2);
return 0;
}
运行结果(EMD和CV_COMP_BHATTACHARYYA对比):