lars76/kmeans-anchor-boxes

Maybe there is a bug about calculating iou?

KevinNuNu opened this issue · 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?

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')