CartToPolar возвращает недостаточно четких углов - PullRequest
0 голосов
/ 26 марта 2019

Моя цель - раскрасить величину градиента камеры в 3 цвета в зависимости от угла, используя opencv.

Чтобы получить величину градиента, я преобразовал кадр из камеры в шкалу серого, затем применил размытие по Гауссу, затем создал sobel на оси x и оси y и преобразовал их в двоичную форму с помощью функции порога. На последнем шаге я использовал функцию cartToPolar (). Но после отладки матрица углов, возвращаемая cartToPolar, имеет только 3 различных значения.

Код, ответственный за создание величины градиента и соответствующих углов

cvtColor(frame, frame, COLOR_BGR2GRAY);
GaussianBlur(frame, gauss, Size(gauss_size, gauss_size), 2.0);

Sobel(gauss, sobel_x, CV_32F, 1.0, 0.0, 3);
threshold(sobel_x, sobel_x_bin, 20, 255, THRESH_BINARY);
Sobel(gauss, sobel_y, CV_32F, 0.0, 1.0, 3);
threshold(sobel_y, sobel_y_bin, 20, 255, THRESH_BINARY);
cartToPolar(sobel_x_bin, sobel_y_bin, gradient, angle, true);

Код ответственный за окраску

gradient.copyTo(gradient_colored);
cvtColor(gradient_colored, gradient_colored, COLOR_GRAY2BGR);
gradient_colored.convertTo(gradient_colored, CV_8UC3, 255);
float angle_value;

Vec3b red = Vec3b(0, 0, 255);
Vec3b green = Vec3b(0, 255, 0);
Vec3b blue = Vec3b(255, 0, 0);
Vec3b white = Vec3b(255, 255, 255);

for (int i = 0; i < gradient.rows; i++) {
    for (int j = 0; j < gradient.cols; j++) {
        angle_value = angle.at<float>(i, j);
        // angle contains only three unique values 0, 44.9, 90, why?

        Vec3b *color = &gradient_colored.at<Vec3b>(i, j);
        if (angle_value > 45 && angle_value <= 135)
            * color = white;
        if (angle_value > 135 && angle_value <= 255)
            * color = blue;
        if (angle_value > 255 && angle_value <= 315)
            * color = green;
        if ((angle_value > 315 && angle_value <= 360) || (angle_value > 0 && angle_value <= 45))
            * color = red;

    }
}

Мне нужна трехцветная (красная, синяя, зеленая, белая, черная) величина градиента в зависимости от вида камеры, но фактический выход имеет один цвет (белый, черный, красный)

1 Ответ

1 голос
/ 26 марта 2019

У вас есть два двоичных изображения (sobel_x_bin и sobel_y_bin), которые вы используете в качестве x и y компонентов градиента в каждом пикселе.Следовательно, каждый пиксель может иметь только четыре различных вектора градиента с тремя разными углами:

  • x=0, y=0 -> Угол не определен.Вероятно, возвращает 0.

  • x=255, y=0 -> Угол равен 0 ° (вектор градиента расположен вдоль оси x).

  • x=0, y=255 -> Угол равен 90 ° (вектор градиента расположен вдоль оси y).

  • x=255, y=255 -> Угол равен 45 °.

Возьмитепосмотрите на массивы, которые вы передаете cartToPolar, и это должно стать ясным.

Почему именно вы устанавливаете градиентные изображения с двоичным порогом?Если вы хотите обрезать все градиенты ниже определенной величины, вы можете использовать другую пороговую функцию (отметьте доступные опции ).Но это должно быть сделано на изображении величины (например, возвращенном cartToPolar), а не на отдельных компонентах.

Возможно, вам следует попробовать это:

cvtColor(frame, frame, COLOR_BGR2GRAY);
GaussianBlur(frame, gauss, Size(gauss_size, gauss_size), 2.0);

Sobel(gauss, sobel_x, CV_32F, 1.0, 0.0, 3);
Sobel(gauss, sobel_y, CV_32F, 0.0, 1.0, 3);
cartToPolar(sobel_x, sobel_y, gradient, angle, true);

, а затем исследоватьоттуда, как получить то, что вам нужно.

...