Получение значения оттенка (HSV / HSB) для RGB с использованием Emgu C # дает неверный результат - PullRequest
0 голосов
/ 22 сентября 2018

Я использую EMGU.CV 3.4.1.2976 (последняя) библиотека для анализа изображений, но я не получаю ожидаемых результатов.Я сравниваю с ImageJ , но любой пакет изображений должен подойти.

Чтобы проверить функциональность, я анализирую простой синий 640x320 jpeg, как показано ниже.Значение RGB для этого изображения составляет 0,0255.

test image to get hue value from

Гистограмма оттенка от ImageJ (значение 170, количество 2048000)

Hue histogram of blue jpeg

Используя приведенный ниже код, я получаю всплеск 120 вместо 170 - счет 2048000 правильный.Что я делаю не так?

    public void AnalyzeEmgu(object image)
    {
        int[] arr = new int[256];

        using (Bitmap bmp = (Bitmap)image)
        {
            using (Image<Hsv, byte> hsvImage = new Image<Hsv, byte>(bmp))
            {
                Image<Gray, byte>[] channels = hsvImage.Split();
                Image<Gray, byte> imgHue = channels[0];

                for (int x = 0; x < imgHue.Rows; x++)
                {
                    for (int y = 0; y < imgHue.Cols; y++)
                    {
                        var b = imgHue.Data[x, y, 0];
                        arr[b]++; // fill array with Hue data. Add 1 (++) to count amount.
                    }
                }
            }
        }

        GC.Collect();
        OnImageFinished(arr); // return array 
    }

  // call function.
  Bitmap bmp =new Bitmap(@"c:\test\blue.jpg");
  AnalyzeEmgu(bmp);

ОБНОВЛЕНИЕ

Получается, мне нужно преобразовать в другое цветовое пространство, но это все еще не на 100% правильно.arr теперь возвращает 171 вместо 170. Это, конечно, лишь небольшая разница, но для более сложных изображений это заметно.

В чем может быть проблема?

    public void AnalyzeEmgu(object image)
    {
        int[] arr = new int[256];

        using (Mat orig = new Mat((string)image, ImreadModes.Color))
        {
            using (Mat hsv = new Mat())
            {
                // convert color to HSV here.
                CvInvoke.CvtColor(orig, hsv, ColorConversion.Bgr2HsvFull);
                Mat[] channels = hsv.Split();

                using (Image<Bgr, byte> img = channels[0].ToImage<Bgr, byte>())
                {
                    for (int x = 0; x < img.Rows; x++)
                    {
                        for (int y = 0; y < img.Cols; y++)
                        {
                            var b = img.Data[x, y, 0];
                            arr[b]++;
                        }
                    }
                }
                channels[1].Dispose();
                channels[2].Dispose();
            }
        }
        GC.Collect();
    }

    OnImageFinished(arr);

1 Ответ

0 голосов
/ 22 сентября 2018

Я не использую ImageJ или EMGU.CV, но я поделюсь некоторыми соображениями для рассмотрения ...

(1)

Правильнозначение оттенка составляет 240 (не 170) градусов.

Оттенок для синего (0,0,255) составляет 240 градусов в цветовом круге.Обратите внимание, что это также можно сказать как -120 .
Эта логика может объяснить, почему вы "получаете пик в 120" для этого конкретного оттенка в функции AnalyzeEmgu.

Можно восстановить из режима минус, добавив 360. Например: myHue = (-120) + 360;, что дает результат: 240.

image

(выше) Изображение предоставлено: http://www.graphic -design.com / Photoshop / color_cast / visible_color_spectrum.html

(2)

Почемугистограмма Хюэ из ImageJ дает 170 ?

Если вы посмотрите на гистограмму изображения, она достигает максимума 255 , но колесо / окружность должны быть максимально 360 .Нет логики, почему они так сделали, но это можно исправить:

IF: 360 / 255 = 1.4117647058823529411764705882353
THEN: 170 * 1.4117647058823529411764705882353 = 240 degrees.

(3)

"Использование кода ниже Iполучите шип на 120 вместо 170 "

Попробуйте

myHue = 360 - 120; //gives 240

На изображении ниже, сделанном в Photoshop, я показываю, что (начиная сверху), еслимы получаем синий цвет, он правильно указан как 240 градусов и находится на расстоянии 88 пикселей при движении вниз.

Обратное движение вверх снизу вверх, и мы видим, что такое же расстояние в 88 пикселей теперь дает 120 (зеленый оттенок).

Цветовое колесо вашего кодаперевернут (вверх ногами).Сравните A с B бок о бок.
Photoshop использует систему A , но ваше значение предполагает, что ваш код выглядит как системный B .

image

...