2013-04-11 3 views
16

Из функций MinAreaRect он возвращает углы в диапазоне 0-360 градусов? Я не уверен, поскольку у меня есть объект, который ориентирован на 90 градусов или около того, но я продолжаю получать либо -1, либо -15 градусов. Это может быть ошибка openCV?Угловые углы MinAreaRect - Неверный относительно угла, возвращаемого

Любое руководство высоко ценится.

Благодаря

ответ

26

Я собираюсь предположить, что вы используете C++, но ответ должен быть таким же, если вы используете C или Python.

Функция minAreaRect, как представляется, дает углы от -90 до 0 градусов, не считая нуля, поэтому интервал [-90, 0).

Функция дает -90 градусов, если прямоугольник, который он выдает, не вращается, т. Е. Прямоугольник имеет две стороны ровно горизонтальную и две стороны точно вертикальные. Когда прямоугольник вращается по часовой стрелке, угол увеличивается (идет к нулю). Когда нуль достигнут, угол, заданный функцией, снова гаснет на -90 градусов.

Так что если у вас длинный прямоугольник от minAreaRect, и он лежит ровно, minAreaRect будет называть угол -90 градусов. Если вы поворачиваете изображение до тех пор, пока прямоугольник, заданный minAreaRect, не станет абсолютно вертикальным, тогда угол снова скажет -90 градусов.

Я не знал об этом (я откладывал от своего проекта OpenCV, чтобы узнать, как это работает: /). Во всяком случае, вот OpenCV программа, которая демонстрирует minAreaRect, если я не объяснил, что это достаточно ясно уже:

#include <stdio.h> 

#include <opencv\cv.h> 
#include <opencv\highgui.h> 

using namespace cv; 

int main() { 
    float angle = 0; 
    Mat image(200, 400, CV_8UC3, Scalar(0)); 
    RotatedRect originalRect; 
    Point2f vertices[4]; 
    vector<Point2f> vertVect; 
    RotatedRect calculatedRect; 

    while (waitKey(5000) != 27) { 
     // Create a rectangle, rotating it by 10 degrees more each time. 
     originalRect = RotatedRect(Point2f(100,100), Size2f(100,50), angle); 

     // Convert the rectangle to a vector of points for minAreaRect to use. 
     // Also move the points to the right, so that the two rectangles aren't 
     // in the same place. 
     originalRect.points(vertices); 
     for (int i = 0; i < 4; i++) { 
      vertVect.push_back(vertices[i] + Point2f(200, 0)); 
     } 

     // Get minAreaRect to find a rectangle that encloses the points. This 
     // should have the exact same orientation as our original rectangle. 
     calculatedRect = minAreaRect(vertVect); 

     // Draw the original rectangle, and the one given by minAreaRect. 
     for (int i = 0; i < 4; i++) { 
      line(image, vertices[i], vertices[(i+1)%4], Scalar(0, 255, 0)); 
      line(image, vertVect[i], vertVect[(i+1)%4], Scalar(255, 0, 0)); 
     } 
     imshow("rectangles", image); 

     // Print the angle values. 
     printf("---\n"); 
     printf("Original angle:    %7.2f\n", angle); 
     printf("Angle given by minAreaRect: %7.2f\n", calculatedRect.angle); 
     printf("---\n"); 

     // Reset everything for the next frame. 
     image = Mat(200, 400, CV_8UC3, Scalar(0)); 
     vertVect.clear(); 
     angle+=10; 
    } 

    return 0; 
} 

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

+0

Чувак вы серьезный драгоценный камень. Спасибо :) – 2013-04-16 17:20:47

+0

Нет проблем :) Документация OpenCV, похоже, пропустила множество важных деталей. –

+0

Еще один вопрос: как я могу получить преобразование 0-360 градусов из rotatedrect, если оно дает только ангелы между -90, -1?И да, opencv, возможно, лучше документирует, когда вы копаете код или их образцы. – 2013-04-16 19:02:47

10

Улучшения от ответа @Adam Гудвин я хочу добавить мой маленький код, который изменяет поведение немного:

Я хотел, чтобы угол между длинной стороной и вертикальной (для меня это самое естественный способ думать о повернутых прямоугольников):

Behold my Paint skills

Если вам нужно то же самое, просто использовать этот код:

void printAngle(RotatedRect calculatedRect){ 
    if(calculatedRect.size.width < calculatedRect.size.height){ 
     printf("Angle along longer side: %7.2f\n", calculatedRect.angle+180); 
    }else{ 
     printf("Angle along longer side: %7.2f\n", calculatedRect.angle+90); 
    } 
} 

Для того, чтобы увидеть его в действии просто вставить его в Адама Goodwins код:

printf("Angle given by minAreaRect: %7.2f\n", calculatedRect.angle); 
printAngle(calculatedRect); 
printf("---\n"); 
+0

если я хочу проверить свой rotatedrect.angle в 360degrees. Как мы можем сделать это. так как ваш текущий код будет работать с 0-180 градусами по вертикали. Любой намек? –

1

После эксперимента, я считаю, что если длинная сторона находится в левой нижней точки, значение угла между длинной стороной и осью Y + , но если длинная сторона находится справа от нижней точки, значение угла находится между длинной стороной и осью X +. Поэтому я использую код, как это (Java):

 rRect = Imgproc.minAreaRect(mop2f); 
     if(rRect.size.width<rRect.size.height){ 
      angle = 90 -rRect.angle; 
     }else{ 
      angle = -rRect.angle; 
     } 

угол от 0 до 180.

Смежные вопросы