Сравнение гистограммы BGR с использованием EmguCV

Я пытаюсь сделать какое-то ранжирование изображений в зависимости от сходства гистограмм. Я беру изображение, и мне нужно сравнить его гистограмму с базой данных изображений, упорядочивая их в зависимости от того, насколько они похожи на исходное изображение. Это должно работать как фильтр, беря подгруппу с наиболее похожими изображениями, а затем сравнивая их с другими методами, более точными и требующими больших затрат (сопоставление с образцом, 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 ответа

Если вам нужна средняя гистограмма, вы также можете напрямую рассчитать ее на сером изображении, например:

/questions/19441714/kak-sozdat-gistogrammu/19441722#19441722

Возможно в вашем образце

(cBlue + cGreen + cRed) / 3.0

Диапазон обрезается, так как он рассчитывается в байтах? Но вы также должны сказать, что этого недостаточно для лучшего понимания проблемы.

Вместо того, чтобы вычислять интенсивность как

(cBlue + cGreen + cRed) / 3,0

Вы можете использовать относительную яркость, которая учитывает чувствительность глаз при объединении трех цветовых компонентов, чтобы получить "уровень серого".

Y = 0,2126 * красный + 0,7152 * зеленый + 0,0722 * синий

Вы можете найти больше информации об относительной яркости здесь

Другие вопросы по тегам