Could anyone share their code for calculating the PGH (Pairwise Geometric Histogram) similarity ? I need to find the most similar object from within a list of images.
I have written up the following code, but the results make no sense. I'd bet I am doing a silly error, and I am stuck.
Any suggestions?
public double GetBestPGHMatch(Contour<Point> currContour, List<Contour<Point>> ContoursList)
{
double match = -1.0d;
DenseHistogram histCurrContour = new DenseHistogram(
new int[2]
{
currContour.Total,
currContour.Total,
},
new RangeF[2]
{
new RangeF(0, 100),
new RangeF(0, 100)
}
);
CvInvoke.cvCalcPGH(currContour.Ptr, histCurrContour.Ptr);
foreach (Contour<Point> contour in ContoursList)
{
DenseHistogram hist = new DenseHistogram(
new int[2]
{
currContour.Total,
currContour.Total,
},
new RangeF[2]
{
new RangeF(0, 100),
new RangeF(0, 100)
}
);
CvInvoke.cvCalcPGH(contour.Ptr, hist.Ptr);
double c = CvInvoke.cvCompareHist(histCurrContour.Ptr, hist.Ptr, Emgu.CV.CvEnum.HISTOGRAM_COMP_METHOD.CV_COMP_CORREL);
if (c > match) match = c;
}
return match;
}
Hope this helps someone, here is how I worked it out, I am using Bhattacharya distance, hence the larger the value, the lower the match. There are other metrics as well, but I found B-distance best for my needs.
public double pghMatchShape(Contour<Point> shape1, Contour<Point> shape2)
{
DenseHistogram hist1 = new DenseHistogram(
new int[2] { 8, 8 },
new RangeF[2] { new RangeF(-180, 180), new RangeF(100, 100) });
DenseHistogram hist2 = new DenseHistogram(
new int[2] { 8, 8 },
new RangeF[2] { new RangeF(-180, 180), new RangeF(100, 100) });
CvInvoke.cvCalcPGH(shape1, hist1.Ptr);
CvInvoke.cvCalcPGH(shape2, hist2.Ptr);
CvInvoke.cvNormalizeHist(hist1.Ptr, 100.0);
CvInvoke.cvNormalizeHist(hist2.Ptr, 100.0);
double corr = CvInvoke.cvCompareHist(hist1, hist2, HISTOGRAM_COMP_METHOD.CV_COMP_BHATTACHARYYA);
return corr;
}