kmeans-anchor-boxes icon indicating copy to clipboard operation
kmeans-anchor-boxes copied to clipboard

Maybe there is a bug about calculating iou?

Open KevinNuNu opened this issue 6 years ago • 1 comments

def iou(box, clusters):
    """
    Calculates the Intersection over Union (IoU) between a box and k clusters.
    :param box: tuple or array, shifted to the origin (i. e. width and height)
    :param clusters: numpy array of shape (k, 2) where k is the number of clusters
    :return: numpy array of shape (k, 0) where k is the number of clusters
    """
    x = np.minimum(clusters[:, 0], box[0])
    y = np.minimum(clusters[:, 1], box[1])
    if np.count_nonzero(x == 0) > 0 or np.count_nonzero(y == 0) > 0:
        raise ValueError("Box has no area")

    intersection = x * y
    box_area = box[0] * box[1]
    cluster_area = clusters[:, 0] * clusters[:, 1]

    iou_ = intersection / (box_area + cluster_area - intersection)

    return iou_

Hi~ I think when u use '/' to calculate iou_ may have a bug. For example, box = np.array([250, 200]), clusters = np.array([[200, 200], [100, 200], [200, 100], [150, 200], [200, 150]]), the output is [0, 0, 0, 0, 0]. Actually, it should be [0.8, 0.4, 0.4, 0.6, 0.6].

I think there are two methods to solve this bug. One is setting boxes' & clusters' data type.

boxes = boxes.astype(np.float32)
clusters = clusters.astype(np.float32)

The other is using np.true_divide() to calculate iou_.

iou_ = np.true_divide(intersection, box_area + cluster_area - intersection)

Do u think so?

KevinNuNu avatar Mar 27 '19 06:03 KevinNuNu

def iou(box, clusters):
    """
    Calculates the Intersection over Union (IoU) between a box and k clusters.
    :param box: tuple or array, shifted to the origin (i. e. width and height)
    :param clusters: numpy array of shape (k, 2) where k is the number of clusters
    :return: numpy array of shape (k, 0) where k is the number of clusters
    """
    x = np.minimum(clusters[:, 0], box[0])
    y = np.minimum(clusters[:, 1], box[1])
    if np.count_nonzero(x == 0) > 0 or np.count_nonzero(y == 0) > 0:
        raise ValueError("Box has no area")

    intersection = x * y
    box_area = box[0] * box[1]
    cluster_area = clusters[:, 0] * clusters[:, 1]

    iou_ = intersection / (box_area + cluster_area - intersection)

    return iou_

Hi~ I think when u use '/' to calculate iou_ may have a bug. For example, box = np.array([250, 200]), clusters = np.array([[200, 200], [100, 200], [200, 100], [150, 200], [200, 150]]), the output is [0, 0, 0, 0, 0]. Actually, it should be [0.8, 0.4, 0.4, 0.6, 0.6].

I think there are two methods to solve this bug. One is setting boxes' & clusters' data type.

boxes = boxes.astype(np.float32)
clusters = clusters.astype(np.float32)

The other is using np.true_divide() to calculate iou_.

iou_ = np.true_divide(intersection, box_area + cluster_area - intersection)

Do u think so? it may cause this error: numpy.core._exceptions.UFuncTypeError: ufunc 'minimum' did not contain a loop with signature matching types (dtype('<U21'), dtype('<U21')) -> dtype('<U21')

JsBlueCat avatar Oct 23 '19 01:10 JsBlueCat