使用EmguCV进行BGR直方图比较

时间:2013-06-06 09:45:16

标签: c# histogram emgucv bgr

我试图根据直方图的相似性进行某种图像排序。我拍摄一张图像,需要将其直方图与根据与源图像的相似程度排序的图像数据库进行比较。这应该像过滤器一样工作,使用具有最相似图像的子组,然后将它们与其他方法进行比较,更准确,计算成本更高(模式匹配,SURF等等)。

这背后的想法是,一些图像有很多蓝色,而在图书馆中有6个图像有很多蓝色,所以它会将这些图像排列得更高。其他图像有很多黄色(蓝色和绿色)......

此时我的代码是:

Image<Bgr, byte> colorCard = frame.Copy();

DenseHistogram histBlue = new DenseHistogram(256, new RangeF(0.0f, 255.0f));
DenseHistogram histRed = new DenseHistogram(256, new RangeF(0.0f, 255.0f));
DenseHistogram histGreen = new DenseHistogram(256, new RangeF(0.0f, 255.0f));

Image<Gray, byte> imgBlue = colorCard[0];
Image<Gray, byte> imgRed = colorCard[1];
Image<Gray, byte> imgGreen = colorCard[2];
imgBlue._EqualizeHist();
imgRed._EqualizeHist();
imgGreen._EqualizeHist();
//Also tried whithout equalizing histograms

histBlue.Calculate(new Image<Gray, byte>[] { imgBlue }, true, null);
histRed.Calculate(new Image<Gray, byte>[] { imgRed }, true, null);
histGreen.Calculate(new Image<Gray, byte>[] { imgGreen }, true, null);

List<Match> matchList = new List<Match>();

foreach (String filename in image_paths)
{
    Image<Bgr, byte> imgToCompare = new Image<Bgr, byte>(filename);
    imgToCompare = imgToCompare.PyrDown().PyrUp().PyrDown().PyrUp();

    DenseHistogram histBlueToCompare = new DenseHistogram(256, new RangeF(0.0f, 255.0f));
    DenseHistogram histRedToCompare = new DenseHistogram(256, new RangeF(0.0f, 255.0f));
    DenseHistogram histGreenToCompare = new DenseHistogram(256, new RangeF(0.0f, 255.0f));

    Image<Gray, byte> imgBlueToCompare = colorCard[0];
    Image<Gray, byte> imgRedToCompare = colorCard[1];
    Image<Gray, byte> imgGreenToCompare = colorCard[2];
    imgBlueToCompare._EqualizeHist();
    imgRedToCompare._EqualizeHist();
    imgGreenToCompare._EqualizeHist();

    histBlueToCompare.Calculate(new Image<Gray, byte>[] { imgBlueToCompare }, true, null);
    histRedToCompare.Calculate(new Image<Gray, byte>[] { imgRedToCompare }, true, null);
    histGreenToCompare.Calculate(new Image<Gray, byte>[] { imgGreenToCompare }, true, null);

    double cBlue = CvInvoke.cvCompareHist(histBlue, histBlueToCompare, Emgu.CV.CvEnum.HISTOGRAM_COMP_METHOD.CV_COMP_CORREL);
    double cRed = CvInvoke.cvCompareHist(histRed, histRedToCompare, Emgu.CV.CvEnum.HISTOGRAM_COMP_METHOD.CV_COMP_CORREL);
    double cGreen = CvInvoke.cvCompareHist(histGreen, histGreenToCompare, Emgu.CV.CvEnum.HISTOGRAM_COMP_METHOD.CV_COMP_CORREL);

    double matchValue = (cBlue + cGreen + cRed) / 3.0;

    matchList.Add(new Match(matchValue, Path.GetFileNameWithoutExtension(filename)));
}

matchList = matchList.OrderBy(X => X.MatchValue).ToList<Match>();
foreach (Match m in matchList)
{
    Logger.Log(m.Card + ": " + m.MatchValue);
}

我可以比较每种颜色直方图,但不知道如何合并这种比较以获得单个值。女巫(cBlue + cGreen + cRed) / 3.0我没有取得好成绩。

我读到的方法是地球移动距离(EMD)。 EmguCV有一个名为cvCalcEMD2的函数,但我不知道如何使用它(参数是什么意思)它并且找不到它的用法示例。

2 个答案:

答案 0 :(得分:1)

如果你想要平均直方图,你也可以直接在灰度图像上计算它,如下所示:

https://stackoverflow.com/a/4906403/586754

也许在你的样本中

(cBlue + cGreen + cRed) / 3.0

范围被裁剪,因为它以字节计算?但是,你应该说如何更好地理解这个问题是不够的。

答案 1 :(得分:0)

而不是将强度计算为

(cBlue + cGreen + cRed)/ 3.0

你可能想要使用相对亮度,它将三种颜色成分组合在一起时考虑到眼睛的敏感度,以获得&#34;灰度级&#34;。

Y = 0.2126 * cRed + 0.7152 * cGreen + 0.0722 * cBlue

您可以找到有关relative luminance here

的更多信息
相关问题