opencv image-processing computer-vision homography ransac

opencv - ¿Cómo comprobar si la matriz de homografía obtenida es buena?



image-processing computer-vision (2)

Edición: esta respuesta es irrelevante para la pregunta, ¡pero la discusión puede ser útil para alguien que intenta utilizar los resultados coincidentes para el reconocimiento como lo hice yo!

Esto podría ayudar a alguien:

Point2f[] objCorners = { new Point2f(0, 0), new Point2f(img1.Cols, 0), new Point2f(img1.Cols, img1.Rows), new Point2f(0, img1.Rows) }; Point2d[] sceneCorners = MyPerspectiveTransform3(objCorners, homography); double marginH = img2.Width * 0.1d; double marginV = img2.Height * 0.1d; bool homographyOK = isInside(-marginH, -marginV, img2.Width + marginH, img2.Height + marginV, sceneCorners); if (homographyOK) for (int i = 1; i < sceneCorners.Length; i++) if (sceneCorners[i - 1].DistanceTo(sceneCorners[i]) < 1) { homographyOK = false; break; } if (homographyOK) homographyOK = isConvex(sceneCorners); if (homographyOK) homographyOK = minAngleCheck(sceneCorners, 20d); private static bool isInside(dynamic minX, dynamic minY, dynamic maxX, dynamic maxY, dynamic coors) { foreach (var c in coors) if ((c.X < minX) || (c.Y < minY) || (c.X > maxX) || (c.Y > maxY)) return false; return true; } private static bool isLeft(dynamic a, dynamic b, dynamic c) { return ((b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X)) > 0; } private static bool isConvex<T>(IEnumerable<T> points) { var lst = points.ToList(); if (lst.Count > 2) { bool left = isLeft(lst[0], lst[1], lst[2]); lst.Add(lst.First()); for (int i = 3; i < lst.Count; i++) if (isLeft(lst[i - 2], lst[i - 1], lst[i]) != left) return false; return true; } else return false; } private static bool minAngleCheck<T>(IEnumerable<T> points, double angle_InDegrees) { //20d * Math.PI / 180d var lst = points.ToList(); if (lst.Count > 2) { lst.Add(lst.First()); for (int i = 2; i < lst.Count; i++) { double a1 = angleInDegrees(lst[i - 2], lst[i-1]); double a2 = angleInDegrees(lst[i], lst[i - 1]); double d = Math.Abs(a1 - a2) % 180d; if ((d < angle_InDegrees) || ((180d - d) < angle_InDegrees)) return false; } return true; } else return false; } private static double angleInDegrees(dynamic v1, dynamic v2) { return (radianToDegree(Math.Atan2(v1.Y - v2.Y, v1.X - v2.X))) % 360d; } private static double radianToDegree(double radian) { var degree = radian * (180d / Math.PI); if (degree < 0d) degree = 360d + degree; return degree; } static Point2d[] MyPerspectiveTransform3(Point2f[] yourData, Mat transformationMatrix) { Point2f[] ret = Cv2.PerspectiveTransform(yourData, transformationMatrix); return ret.Select(point2fToPoint2d).ToArray(); }

Esta pregunta ya fue asked , pero todavía no lo entiendo. cv::findHomography una matriz de homografía llamando a cv::findHomography desde un conjunto de puntos. Necesito comprobar si es relevante o no.
El método propuesto es calcular el error de reproyección máximo para inliers y compararlo con un umbral. Pero después de tal filtración, sigo recibiendo transformaciones demenciales con el cuadro delimitador de objetos que se transforma en casi una línea recta o en algún extraño cuadrilátero no convexo, con auto-intersecciones, etc.
¿Qué restricciones se pueden usar para verificar si la matriz de homografía es adecuada?


Tu pregunta es matemática. Dada una matriz de 3x3 decide si representa una buena transformación rígida. Es difícil definir qué es "bueno", pero aquí hay algunas pistas que pueden ayudarlo.

  1. La homografía debe preservar la dirección de los puntos poligonales. Diseñar una prueba simple. Los puntos (0,0), (imwidth, 0), (ancho, altura), (0, altura) representan un cuadrilátero con puntos dispuestos en el sentido de las agujas del reloj. Aplique homografía en esos puntos y vea si todavía están dispuestos en el sentido de las agujas del reloj, si se vuelven en sentido contrario a las agujas del reloj, su homografía está volteando (reflejando) la imagen, que a veces todavía está bien. Pero si tus puntos están fuera de orden entonces tienes una "mala homografía"
  2. La homografía no cambia demasiado la escala del objeto. Por ejemplo, si espera que se reduzca o aumente la imagen en un factor de hasta X, simplemente verifique esta regla. Transforme los 4 puntos (0,0), (imwidth, 0), (ancho-1, altura), (0, altura) con homografía y calcule el área del cuadrilátero (método de cálculo de área abierta del polígono) si la relación Si las áreas son demasiado grandes (o demasiado pequeñas), es probable que tenga un error.
  3. La buena homografía es usualmente utiliza valores bajos de perspectividad. Normalmente, si el tamaño de la imagen es ~ 1000x1000 píxeles, esos valores deben ser ~ 0.005-0.001. La alta perspectividad causará enormes distorsiones que probablemente sean un error. Si no sabes dónde están ubicados esos valores, lee mi publicación: tratar de entender la Transformada Afín . Explica la transformación afín matemática y los otros 2 valores son parámetros de perspectiva.

Creo que si marca la condición 3 anterior (la condición 2 es la más importante) podrá detectar la mayoría de los problemas. Buena suerte