But processing time is slow.
For using the EMD compare, we should make signature value.
The EMD method compares two signatures value.
Firstly, we prepare histograms of 2 images.
And convert values of histrogram to signature.
A configuration of signature values is very simple.
bins value, x index, y index.
bins value, x index, y index.
bins value, x index, y index.
bins value, x index, y index.
bins value, x index, y index.
....
Of course this type is in case of 2d histogram.
More detail, see the source code.
In here I cannot explain earth mover distance algorithm.
please refer to internet information.
thank you.
origin images
result
...
#include < iostream> #include < vector> #include < stdio.h> #include < opencv2\opencv.hpp> #ifdef _DEBUG #pragma comment(lib, "opencv_core249d.lib") #pragma comment(lib, "opencv_imgproc249d.lib") //MAT processing #pragma comment(lib, "opencv_highgui249d.lib") #else #pragma comment(lib, "opencv_core249.lib") #pragma comment(lib, "opencv_imgproc249.lib") #pragma comment(lib, "opencv_highgui249.lib") #endif using namespace cv; using namespace std; int main() { //read 2 images for histogram comparing /////////////////////////////////////////////////////////////////////////////////////////////////////////////// Mat imgA, imgB; imgA = imread(".\\image1.jpg"); imgB = imread(".\\image2.jpg"); imshow("img1", imgA); imshow("img2", imgB); //variables preparing /////////////////////////////////////////////////////////////////////////////////////////////////////////////// int hbins = 30, sbins = 32; int channels[] = {0, 1}; int histSize[] = {hbins, sbins}; float hranges[] = { 0, 180 }; float sranges[] = { 0, 255 }; const float* ranges[] = { hranges, sranges}; Mat patch_HSV; MatND HistA, HistB; //cal histogram & normalization /////////////////////////////////////////////////////////////////////////////////////////////////////////////// cvtColor(imgA, patch_HSV, CV_BGR2HSV); calcHist( &patch_HSV, 1, channels, Mat(), // do not use mask HistA, 2, histSize, ranges, true, // the histogram is uniform false ); normalize(HistA, HistA, 0, 1, CV_MINMAX); cvtColor(imgB, patch_HSV, CV_BGR2HSV); calcHist( &patch_HSV, 1, channels, Mat(),// do not use mask HistB, 2, histSize, ranges, true, // the histogram is uniform false ); normalize(HistB, HistB, 0, 1, CV_MINMAX); //compare histogram /////////////////////////////////////////////////////////////////////////////////////////////////////////////// int numrows = hbins * sbins; //make signature Mat sig1(numrows, 3, CV_32FC1); Mat sig2(numrows, 3, CV_32FC1); //fill value into signature for(int h=0; h< hbins; h++) { for(int s=0; s< sbins; ++s) { float binval = HistA.at< float>(h,s); sig1.at< float>( h*sbins + s, 0) = binval; sig1.at< float>( h*sbins + s, 1) = h; sig1.at< float>( h*sbins + s, 2) = s; binval = HistB.at< float>(h,s); sig2.at< float>( h*sbins + s, 0) = binval; sig2.at< float>( h*sbins + s, 1) = h; sig2.at< float>( h*sbins + s, 2) = s; } } //compare similarity of 2images using emd. float emd = cv::EMD(sig1, sig2, CV_DIST_L2); //emd 0 is best matching. printf("similarity %5.5f %%\n", (1-emd)*100 ); waitKey(0); return 0; }...