Saltar al contenido

Detecta el centro y el ángulo de los rectángulos en una imagen usando Opencv

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:

ingrese la descripción de la imagen aquí

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!

ingrese la descripción de la imagen aquí

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):

ingrese la descripción de la imagen aquí

Obtengo esos resultados (los puntos azules son centros de rectángulo de referencia proporcionados por el operador):

ingrese la descripción de la imagen aquí

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:

  1. Etiquetado de componentes conectados para detectar cada patrón (en su caso, los rectángulos)
  2. Separar los patrones en diferentes imágenes.
  3. (opcional) si el patrón no son todos rectángulos, use índices de forma para discriminarlos
  4. 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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags :

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *