opencv - Ángulos MinAreaRect: no está seguro del ángulo devuelto
angle (3)
De las funciones de MinAreaRect, ¿devuelve ángulos en el rango de 0-360 grados? No estoy seguro ya que tengo un objeto que está orientado a 90 grados aproximadamente, pero sigo obteniendo -1 o -15 grados. ¿Podría ser esto un error openCV?
Cualquier orientación muy apreciada.
Gracias
Después del experimento, encuentro que si el lado largo está a la izquierda del Punto inferior, el valor del ángulo está entre el lado largo y el eje Y +, pero si el lado largo está a la derecha del Punto inferior, el valor del ángulo es entre largo Lateral y eje X +. Entonces uso el código como este (java):
rRect = Imgproc.minAreaRect(mop2f);
if(rRect.size.width<rRect.size.height){
angle = 90 -rRect.angle;
}else{
angle = -rRect.angle;
}
El ángulo es de 0 a 180.
Mejorando la respuesta de @Adam Goodwin, quiero agregar mi pequeño código que cambia un poco el comportamiento:
Quería tener el ángulo entre el lado más largo y el vertical (para mí es la forma más natural de pensar en rectángulos girados):
Si necesitas lo mismo, solo usa este código:
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);
}
}
Para verlo en acción simplemente insértelo en el código de Adam Goodwins:
printf("Angle given by minAreaRect: %7.2f/n", calculatedRect.angle);
printAngle(calculatedRect);
printf("---/n");
Voy a asumir que estás usando C ++, pero la respuesta debería ser la misma si estás usando C o Python.
La función minAreaRect
parece dar ángulos que van desde -90 a 0 grados, sin incluir cero, por lo que un intervalo de [-90, 0).
La función da -90 grados si el rectángulo que genera no se gira, es decir, el rectángulo tiene dos lados exactamente horizontales y dos lados exactamente verticales. A medida que el rectángulo gira hacia la derecha, el ángulo aumenta (va hacia cero). Cuando se alcanza el cero, el ángulo dado por la función regresa nuevamente a -90 grados.
Por lo tanto, si tiene un rectángulo largo de minAreaRect
y está acostado, minAreaRect
llamará al ángulo de -90 grados. Si gira la imagen hasta que el rectángulo dado por minAreaRect
esté perfectamente en posición vertical, entonces el ángulo dirá -90 grados nuevamente.
En realidad, no sabía nada de esto (procrastino de mi proyecto OpenCV para averiguar cómo funciona: /). De todos modos, aquí hay un programa OpenCV que muestra minAreaRect
si aún no lo he explicado lo suficientemente claro:
#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;
}
Esto le permite ver fácilmente cómo el ángulo y la forma de un rectángulo dibujado manualmente se comparan con la interpretación minAreaRect
del mismo rectángulo.