Solución:
Prueba la intersección sobre Union
Intersection over Union es una métrica de evaluación que se utiliza para medir la precisión de un detector de objetos en un conjunto de datos en particular.
Más formalmente, para aplicar Intersection over Union para evaluar un detector de objetos (arbitrario), necesitamos:
- Los cuadros delimitadores de verdad del terreno (es decir, los cuadros delimitadores etiquetados a mano del conjunto de prueba que especifican en qué parte de la imagen está nuestro objeto).
- Los cuadros delimitadores predichos de nuestro modelo.
A continuación, he incluido un ejemplo visual de un cuadro delimitador de verdad del terreno frente a un cuadro delimitador predicho:
El cuadro delimitador predicho se dibuja en rojo, mientras que el cuadro delimitador de verdad del terreno (es decir, etiquetado a mano) se dibuja en verde.
En la figura de arriba podemos ver que nuestro detector de objetos ha detectado la presencia de una señal de alto en una imagen.
Por lo tanto, la intersección informática sobre la unión se puede determinar mediante:
Siempre que tengamos estos dos conjuntos de cuadros delimitadores, podemos aplicar Intersección sobre Unión.
Aquí está el código de Python
# import the necessary packages
from collections import namedtuple
import numpy as np
import cv2
# define the `Detection` object
Detection = namedtuple("Detection", ["image_path", "gt", "pred"])
def bb_intersection_over_union(boxA, boxB):
# determine the (x, y)-coordinates of the intersection rectangle
xA = max(boxA[0], boxB[0])
yA = max(boxA[1], boxB[1])
xB = min(boxA[2], boxB[2])
yB = min(boxA[3], boxB[3])
# compute the area of intersection rectangle
interArea = (xB - xA) * (yB - yA)
# compute the area of both the prediction and ground-truth
# rectangles
boxAArea = (boxA[2] - boxA[0]) * (boxA[3] - boxA[1])
boxBArea = (boxB[2] - boxB[0]) * (boxB[3] - boxB[1])
# compute the intersection over union by taking the intersection
# area and dividing it by the sum of prediction + ground-truth
# areas - the interesection area
iou = interArea / float(boxAArea + boxBArea - interArea)
# return the intersection over union value
return iou
los gt
y pred
están
-
gt
: El cuadro delimitador de la verdad fundamental. -
pred
: El cuadro delimitador previsto de nuestro modelo.
Para obtener más información, puede hacer clic en esta publicación.
1) Tiene dos cuadros delimitadores superpuestos. Calcula la intersección de las cajas, que es el área de superposición. Calcula la unión de los cuadros superpuestos, que es la suma de las áreas de los cuadros completos menos el área de superposición. Luego divide la intersección por la unión. Hay una función para eso en la Caja de herramientas del sistema de visión por computadora llamada bboxOverlapRatio.
2) Generalmente, no desea concatenar los canales de color. En su lugar, lo que desea es un histograma 3D, donde las dimensiones son H, S y V.
La respuesta actual ya explicaba claramente la pregunta. Así que aquí proporciono una versión un poco mejor de IoU con Python que no se rompe cuando dos cuadros delimitadores no se cruzan.
import numpy as np
def IoU(box1: np.ndarray, box2: np.ndarray):
"""
calculate intersection over union cover percent
:param box1: box1 with shape (N,4) or (N,2,2) or (2,2) or (4,). first shape is preferred
:param box2: box2 with shape (N,4) or (N,2,2) or (2,2) or (4,). first shape is preferred
:return: IoU ratio if intersect, else 0
"""
# first unify all boxes to shape (N,4)
if box1.shape[-1] == 2 or len(box1.shape) == 1:
box1 = box1.reshape(1, 4) if len(box1.shape) <= 2 else box1.reshape(box1.shape[0], 4)
if box2.shape[-1] == 2 or len(box2.shape) == 1:
box2 = box2.reshape(1, 4) if len(box2.shape) <= 2 else box2.reshape(box2.shape[0], 4)
point_num = max(box1.shape[0], box2.shape[0])
b1p1, b1p2, b2p1, b2p2 = box1[:, :2], box1[:, 2:], box2[:, :2], box2[:, 2:]
# mask that eliminates non-intersecting matrices
base_mat = np.ones(shape=(point_num,))
base_mat *= np.all(np.greater(b1p2 - b2p1, 0), axis=1)
base_mat *= np.all(np.greater(b2p2 - b1p1, 0), axis=1)
# I area
intersect_area = np.prod(np.minimum(b2p2, b1p2) - np.maximum(b1p1, b2p1), axis=1)
# U area
union_area = np.prod(b1p2 - b1p1, axis=1) + np.prod(b2p2 - b2p1, axis=1) - intersect_area
# IoU
intersect_ratio = intersect_area / union_area
return base_mat * intersect_ratio