Queremos mostrarte la mejor respuesta que hallamos en todo internet. Nosotros esperamos que te sea útil y si quieres compartir cualquier detalle que nos pueda ayudar a crecer hazlo libremente.
Así es como puedes hacerlo con la función minAreaRect de openCV. Está escrito en C ++, pero probablemente pueda adaptarlo fácilmente, ya que casi solo se usaron funciones de OpenCV.
cv::Mat input = cv::imread("../inputData/rectangles.png");
cv::Mat gray;
cv::cvtColor(input,gray,CV_BGR2GRAY);
// since your image has compression artifacts, we have to threshold the image
int threshold = 200;
cv::Mat mask = gray > threshold;
cv::imshow("mask", mask);
// extract contours
std::vector > contours;
cv::findContours(mask, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
for(int i=0; i
resultando en esta imagen:
como puede ver, los ángulos probablemente no sean los que desea (porque usan aleatoriamente la línea más larga o la más pequeña como referencia). En su lugar, puede extraer los lados más largos de los rectángulos y calcular el ángulo manualmente.
Si elige el borde más largo de los rectos rotados y calcula el ángulo a partir de él, se ve así:
// choose the longer edge of the rotated rect to compute the angle
cv::Point2f edge1 = cv::Vec2f(rect_points[1].x, rect_points[1].y) - cv::Vec2f(rect_points[0].x, rect_points[0].y);
cv::Point2f edge2 = cv::Vec2f(rect_points[2].x, rect_points[2].y) - cv::Vec2f(rect_points[1].x, rect_points[1].y);
cv::Point2f usedEdge = edge1;
if(cv::norm(edge2) > cv::norm(edge1))
usedEdge = edge2;
cv::Point2f reference = cv::Vec2f(1,0); // horizontal edge
angle = 180.0f/CV_PI * acos((reference.x*usedEdge.x + reference.y*usedEdge.y) / (cv::norm(reference) *cv::norm(usedEdge)));
dando este resultado, ¡que debería ser lo que estás buscando!
EDITAR: Parece que el operador no usa la imagen de entrada que publicó, porque los centros de los rectángulos de referencia estarían fuera de la imagen.
Usando esta entrada (reescalada manualmente pero probablemente aún no sea óptima):
Obtengo esos resultados (los puntos azules son centros de rectángulo de referencia proporcionados por el operador):
Comparando la referencia con las detecciones:
reference (x,y,angle) detection (x,y,angle)
(320,240,0) (320, 240, 180) // angle 180 is equal to angle 0 for lines
(75,175,90) (73.5, 174.5, 90)
(279,401,170) (279.002, 401.824, 169.992)
(507,379,61) (507.842, 379.75, 61.1443)
(545,95,135) (545.75, 94.25, 135)
(307,79,37) (306.756, 77.8384, 37.1042)
Sin embargo, me encantaría ver la imagen de entrada REAL, tal vez el resultado sea aún mejor.
Aquí sabrás como podrás hacerlo:
- Etiquetado de componentes conectados para detectar cada patrón (en su caso, los rectángulos)
- Separar los patrones en diferentes imágenes.
- (opcional) si el patrón no son todos rectángulos, use índices de forma para discriminarlos
- Calcule el eje principal utilizando el análisis de componentes principales (PCA), le dará el ángulo que está buscando.
Comentarios y calificaciones de la guía
Puedes amparar nuestro análisis añadiendo un comentario o dejando una valoración te lo agradecemos.