利用EmguCV比较BGR直方图
本文关键字:直方图 BGR 比较 EmguCV 利用 | 更新日期: 2023-09-27 18:17:16
我正在尝试根据直方图相似度进行某种图像排名。我取了一张图像,需要将其直方图与图像数据库进行比较,这些图像的排序取决于它们与源图像的相似程度。这应该像过滤器一样工作,取最相似图像的子组,然后将它们与其他更准确和计算成本更高的方法(模式匹配,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);
}
我可以比较每个颜色直方图,但不知道如何合并这些比较以获得单个值。Witch (cBlue + cGreen + cRed) / 3.0
我没有得到好的结果。
我读到一个方法来做到这一点是地球移动距离(EMD)。EmguCV有一个叫做cvCalcEMD2
的函数,但是我不知道如何使用它(参数意味着什么),也找不到它的用法的例子。
如果你想要平均直方图,你也可以直接在灰色图像上计算它,像这样:
https://stackoverflow.com/a/4906403/586754也许在你的样本
(cBlue + cGreen + cRed) / 3.0
范围被裁剪,因为它计算在字节?但是,你也应该说,更好地理解问题是不够的。
不计算强度
(cBlue + cGreen + cRed)/3.0
你可能想使用相对亮度,当结合三种颜色成分得到"灰度级"时,它考虑了眼睛的敏感度。
Y = 0.2126 * cRed + 0.7152 * cGreen + 0.0722 * cBlue
你可以在这里找到更多关于相对亮度的信息