Some time ago, cwj649956781 said that he did not understand the role of the cvCalEMD2 function. Because of the time relationship, he only replied to it now. Sorry!
1. What is EMD?
The so-called EMD is actually the abbreviation of Earth Mover's Distance, that is, land moving Distance.
2. What is EMD?
1) cause:
Light changes can cause the color value to drift of the image. Although the color histogram shape is not changed, the position of the color value is changed and the matching fails.
2) results:
Therefore, we need to use EMD to solve this problem. Use the histogram distance measurement to replace the Histogram Matching policy, so that the distance between the two histograms can be compared as compared with the histogram comparison.
3) essence of EMD:
It is actually how a measurement converts the shape of a histogram to the shape of another histogram, including moving part or all of the histogram to a new position, which can be measured on the histogram of any dimension.
3. How to calculate EMD?
Opencv provides the following functions:
Function:
Float cvCalcEMD2 (
Const CvArr * signature1,
Const CvArr * signature2,
Int distance_type,
CvDistanceFunction distance_func = NULL,
Const CvArr * cost_matrix = NULL,
CvArr * flow = NULL,
Float * lower_bound = NULL,
Void * userdata = NULL
);
1) parameter explanation:
Many default parameters in the function can be simplified
Float cvCalcEMD2 (
Const CvArr * signature1,
Const CvArr * signature2,
Int distance_type
);
Distance_type indicates the distance type.
It can be the distance from Manhattan (CV_DIST_L1)
Euclidean distance (CV_DIST_L2 );
The signature array is floating point type.
Each row includes the bin of the histogram (the number of sticks in the image point) and coordinates.
2) how to generate signature?
Learning opencv provides an example
Two histograms, hist1 and hist2, are given.
How to convert them to signature? Next we will use the code to illustrate the problem.
CvMat * sig1, sig2;
Int numrows = h_bins * s_bins;
// Used to store the signature matrix. Note that the type is floating-point www.2cto.com.
Sig1 = cvCreateMat (numrows, 3, CV_32FC1); // 1 count + 2 coords = 3
Sig2 = cvCreateMat (numrows, 3, CV_32FC1); // sigs are of type float.
For (int h = 0; 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); // bin value
CvSet2D (sig1, h * s_bins + s, 1, cvScalar (h); // Coord 1
CvSet2D (sig1, h * s_bins + s, 2, cvScalar (s); // Coord 2
Bin_val = cvQueryHistValue_2D (hist2, h, s );
CvSet2D (sig2, h * s_bins + s, 0, cvScalar (bin_val); // bin value
CvSet2D (sig2, h * s_bins + s, 1, cvScalar (h); // Coord 1
CvSet2D (sig2, h * s_bins + s, 2, cvScalar (s); // Coord 2
}
}
3) Calculate EMD:
After signature is completed, you can calculate it.
Float emd = cvCalcEMD2 (sig1, sig2, CV_DIST_L2 );
Printf ("% f;", emd );
All we get is the distance measurement EMD.
4. Thinking:
In fact, the EMD is still able to calculate the correlation between two histograms when the light changes and the result cannot be matched. Of course, it is measured by the emd value. In this way, the matching effect is achieved when the light changes.
From Zhang Xiaoxiao's Technical Workshop