Как нарисовать нужную линию из вывода функции HoughLines в OpenCV C++?

Контекст:

На странице № 8 в этой лекции говорится, что функция OpenCV HoughLines возвращает массив N x 2 параметров строки rho и theta, который хранится в массиве, называемом строками.

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

Код:

    //Assuming we start our program with the Input Image as shown below.

    vector<Vec2f> lines; 
    //This array will be used for storing rho and theta as N x 2 array

    HoughLines(bw_roi, lines, 1, CV_PI/180, 70, 0, 0); '
    //The input bw_roi is a canny image with detected edges

    //These formulae below do the line estimation based on rho and theta
    for( size_t i = 0; i < lines.size(); i++ )
    {
        float rho = lines[i][0], theta = lines[i][1];
        Point2d pt1, pt2;
        double m;
        double a = cos(theta), b = sin(theta);
        double x0 = a*rho, y0 = b*rho;

        //When we use 1000 below we get Observation 1 output. 
        //But if we use 200, we get Observation 2 output.

        pt1.x = cvRound(x0 + 1000*(-b)); 
        pt1.y = cvRound(y0 + 1000*(a));
        pt2.x = cvRound(x0 - 1000*(-b));
        pt2.y = cvRound(y0 - 1000*(a));

        line(frame, pt1, pt2, Scalar(0,0,255), 3, LINE_AA);
        //This line function is independent of HoughLines function    
        //and is used for drawing any type of line in OpenCV

Входное изображение:

Наблюдение 1:

Наблюдение 2:

Проблема:

В приведенном выше коде, если мы поиграем с числом, которое мы умножаем на a, -a, b & -b, мы получим строки различной длины. Наблюдение 2 было получено, когда я умножил на 200 вместо 1000 (что приводит к Наблюдению 1).

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

Вопрос:

Когда мы рисуем линии из вывода HoughLines, как мы можем контролировать, где начинается и заканчивается наша линия?

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

1 ответ

Решение

Дано

a = cos(theta)
b = sin(theta)

x0 = a * rho
y0 = b * rho

Вы можете написать формулу для всех точек, лежащих на линии, определенной (rho, theta) как

x = x0 - c * b
y = y0 + c * a

где c расстояние от контрольной точки (пересекается с перпендикулярной линией через начало координат).

В вашем случае вы оценили это с c = 1000 а также c = -1000 чтобы получить две точки, чтобы провести линию между.

Вы можете переписать их как

c = (x0 - x) / b
c = (y - y0) / a

А затем используйте подстановку для вычисления горизонтальных и вертикальных перехватов:

x = x0 - ((y - y0) / a) * b

или же

y = y0 + ((x0 - x) / b) * a

NB: Будьте осторожны, чтобы правильно обрабатывать случаи, когда a или же b 0


Допустим, у вас есть изображение 800x600 (чтобы цифры были простыми). Мы можем определить нижний край изображения как линию y = 599, Рассчитать стоимость x где ваша строка перехватывает его, используя приведенную выше формулу.

  • Если точка пересечения находится на изображении (0 <= x < 800), это ваша отправная точка.
  • Если это слева (x < 0), найдите перехват с линией x = 0 использовать в качестве отправной точки.
  • Если это справа (x >= 800), найдите перехват с линией x = 799 использовать в качестве отправной точки.

Затем используйте аналогичную технику, чтобы найти вторую точку, чтобы можно было нарисовать линию.

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