Posterior a investigar en varios repositorios y páginas finalmente hemos dado con la solución que te compartimos aquí.
Solución:
Calcule el área de la intersección, que también es un rectángulo:
SI = Max(0, Min(XA2, XB2) - Max(XA1, XB1)) * Max(0, Min(YA2, YB2) - Max(YA1, YB1))
A partir de ahí, calcula el área de la unión:
SU = SA + SB - SI
Y puedes considerar la proporción
SI / SU
(100% en caso de superposición perfecta, hasta 0%).
Si bien la respuesta aceptada es correcta, creo que vale la pena explorar esta respuesta de una manera que haga que la justificación de la respuesta sea completamente obvia. Este es un algoritmo demasiado común para tener una respuesta incompleta (o peor, controvertida). Además, con solo un vistazo de pasada a la fórmula dada, puede perderse la belleza y la extensibilidad del algoritmo, y las decisiones implícitas que se están tomando.
Primero, considere una forma de definir una caja bidimensional con:
- (x, y) para el punto superior izquierdo
- (x, y) para el punto inferior derecho
Esto podría verse así:
Indico la parte superior izquierda con un triángulo y la parte inferior derecha con un círculo. Esto es para evitar una sintaxis opaca como x1, x2
para este ejemplo.
Dos rectángulos superpuestos podrían verse así:
Observe que para encontrar la superposición, está buscando el lugar donde chocan el naranja y el azul:
Una vez que reconoces esto, resulta obvio que la superposición es el resultado de encontrar y multiplicar estas dos líneas oscurecidas:
La longitud de cada línea es el valor mínimo de los dos puntos del círculo, menos el valor máximo de los dos puntos del triángulo.
Aquí, estoy usando un triángulo de dos tonos (y un círculo) para mostrar que los puntos naranja y azul se comparan entre sí. La letra minúscula “y” después del triángulo de dos tonos indica que los triángulos se comparan a lo largo del eje y, la “x” pequeña significa que se comparan a lo largo del eje x.
Por ejemplo, para encontrar la longitud de la línea azul oscura, puede ver que los triángulos se comparan para buscar el valor máximo entre los dos. El attribute que se compara es la x attribute. El valor máximo de x entre los triángulos es 210.
Otra forma de decir lo mismo es: la longitud de la nueva línea que se ajusta a las líneas naranja y azul se calcula restando el punto más alejado en el lado más cercano de la línea del punto más cercano en el lado más alejado de la línea.
Encontrar esas líneas brinda información completa sobre las áreas superpuestas.
Una vez que tenga esto, encontrar el porcentaje de superposición es trivial:
Pero espere, si el rectángulo naranja no se superpone con el azul, entonces tendrá un problema:
Con este ejemplo, obtiene un -850 para nuestra área superpuesta, eso no puede ser correcto. Peor aún, si una detección no se superpone con ninguna dimensión (ni en el eje x ni en el eje y), obtendrá un número positivo porque ambos las dimensiones son negativas. Por eso ves el Max(0, ...) * Max(0, ...)
como parte de la solución; asegura que si alguna de las superposiciones es negativa, obtendrá un 0 de su función.
La fórmula final acorde con nuestra simbología:
Vale la pena señalar que el uso de max(0, ...)
La función puede no ser necesaria. Es posible que desee saber si algo se superpone a lo largo de una de sus dimensiones en lugar de todas; si usa max, borrará esa información. Por esa razón, considere cómo desea tratar los cuadros delimitadores que no se superponen. Normalmente, la función max está bien de usar, pero vale la pena estar al tanto de lo que está haciendo.
Finalmente, observe que dado que esta comparación solo se refiere a medidas lineales, se puede escalar a dimensiones arbitrarias o cuadriláteros superpuestos arbitrarios.
Para resumir:
intersecting_area =
max(0, min(orange.circle.x, blue.circle.x) - max(orange.triangle.x, blue.triangle.x)) * max(0, min(orange.circle.y, blue.circle.y) - max(orange.triangle.y, blue.triangle.y))
percent_coverage = intersecting_area / (orange_area + blue_area - intersecting_area)
La fórmula para la intersección será
SI= Max(0, Min(XA2, XB2) - Max(XA1, XB1)) * Max(0, Min(YA2, YB2) - Max(YA1, YB1))
entonces la unión será S=SA+SB-SI
Y finalmente, la proporción será SI / S
.
Al final de todo puedes encontrar las críticas de otros creadores, tú aún eres capaz dejar el tuyo si dominas el tema.