Je lisais le document: Ferrari et al. dans la section "Mesures d'affinité". J'ai compris que Ferrari et al. essaie d'obtenir l'affinité en:
Cependant, j'ai 2 problèmes principaux:
Des suggestions ou des solutions à mes problèmes décrits ci-dessus? Merci et votre aide est très appréciée.
1) Vous avez deux boîtes englobantes qui se chevauchent. Vous calculez l'intersection des boîtes, qui est la zone du chevauchement. Vous calculez l'union des boîtes qui se chevauchent, qui est la somme des zones de toutes les boîtes moins la zone du chevauchement. Ensuite, vous divisez l'intersection par l'union. Il existe une fonction pour cela dans la boîte à outils du système de vision par ordinateur appelée bboxOverlapRatio .
2) En règle générale, vous ne souhaitez pas concaténer les canaux de couleur. Ce que vous voulez à la place, c'est un histogramme 3D, où les dimensions sont H, S et V.
Essayez l'intersection sur Union
Intersection over Union est une métrique d'évaluation utilisée pour mesurer la précision d'un détecteur d'objet sur un ensemble de données particulier.
Plus formellement, afin d'appliquer Intersection sur Union pour évaluer un détecteur d'objets (arbitraire), nous avons besoin de:
Ci-dessous, j'ai inclus un exemple visuel d'un cadre de délimitation de la vérité par rapport à un cadre de délimitation prévu:
La zone de délimitation prévue est dessinée en rouge tandis que la zone de délimitation de la vérité au sol (c'est-à-dire étiquetée à la main) est dessinée en vert.
Dans la figure ci-dessus, nous pouvons voir que notre détecteur d'objet a détecté la présence d'un panneau d'arrêt dans une image.
Le calcul de l'intersection sur l'Union peut donc être déterminé via:
Tant que nous avons ces deux ensembles de boîtes englobantes, nous pouvons appliquer Intersection sur Union.
Voici le code 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
gt
et pred
sont
gt
: le cadre de délimitation de la vérité au sol.pred
: le cadre de délimitation prévu de notre modèle.Pour plus d'informations, vous pouvez cliquer sur cet article
La réponse actuelle expliquait déjà clairement la question. Donc, ici, je fournis une version un peu meilleure de l'IoU avec Python qui ne se casse pas lorsque deux boîtes englobantes ne se croisent pas.
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