0

I want to calculate the ratio of detected rectangle from many images by two detector based on deep learning. for example with below picture, firstly, the first detector detects big circles (c1 and c2), and the second detector detects small circles (d1 and d2). Now, first detector returns the coordinates of c1 and c2, second detector also those of d1 and d2.

Soenter image description here I want to make the function and code that can calculate the ratio d1/ c1 and d2 / c2 automatically. so, my idea is that if coordinate of small one(e.g. d1, d2) is included in corresponding big one (e.g. c1, c2), they are matched for calculation of ratio.

c1 coordinate (xmin, ymin, xmax, ymax) : (10, 10, 30, 30) d1 coorinate : (13, 15, 20, 23)

c2 coordinate : (20, 20, 40, 40) d2 coordinate : (25, 24, 32, 33)

But, I don't know many function of OpenCV and python. Could you please make some code, function or recommend library?

Thank you

Seunghyeon
  • 103
  • 1
  • 2
  • 10
  • 1
    "Could you please make some code" is a sure way to get your question downvoted and closed. If you have already detectors that return coordinates, then writing the function you describe sounds rather trivial (at least in an inefficient way) and doesn't need a library. Please share your code an efforts, and ask questions about where you are precisely stuck. – Ash Nov 14 '20 at 10:19
  • As you know, code is very long in object detection based on deep learning. it is difficult to post everything. so I briefly explain what is the faced problem. – Seunghyeon Nov 14 '20 at 10:44
  • I understand, but your problem, if I'm not mistaken, doesn't concern the deep learning part, it's about some post-processing, and what you need is a function `f(coordintaes_of_detected_objects)` that returns the ratios. What I'm asking for is that if possible, you share what you already have done for that function. Your idea sounds fine, so i'm curious to see why you haven't implemented a brute-force version of it. Maybe I'm missing something trivial, in that case I apologize. – Ash Nov 14 '20 at 11:43
  • 1
    Thank you for commenting. I found this question and answer (https://stackoverflow.com/questions/40622016/efficient-way-to-find-overlapping-of-n-rectangles/40673354). I hope that it will be useful for other people who face similar problem. – Seunghyeon Nov 14 '20 at 14:41

1 Answers1

2

The metric which is generally used for this task is "Intersection over Union" i.e. IOU.

With inputs for bounding box (rectangle) in this format [50, 60, 200, 150], you can write a custom function for it like this -

def intersection_over_union(box1, box2):
    # Get coordinates of the intersection 
    x1 = max(box1[0], box2[0])
    y1 = max(box1[1], box2[1])
    x2 = min(box1[2], box2[2])
    y2 = min(box1[3], box2[3])

    # Get the area of intersection rectangle
    intersection = max(0, x2 - x1 + 1) * max(0, y2 - y1 + 1)

    # Get the area of both rectangles
    box1Area = (box1[2] - box1[0] + 1) * (box1[3] - box1[1] + 1)
    box2Area = (box2[2] - box2[0] + 1) * (box2[3] - box2[1] + 1)

    iou = intersection / float(box1Area + box2Area - intersection)

    return iou

Note that this needs the bounding boxes are returned in the standard format where following conditions are correct:

assert box1['x1'] <= box1['x2']
assert box1['y1'] <= box1['y2']
assert box2['x1'] <= box2['x2']
assert box2['y1'] <= box2['y2']

More details in this answer.

If bounding box pair does not hold that condition, its best to use jaccard_score (another name for IOU) from sklearn

from sklearn.metrics import jaccard_score
import numpy as np

box1 = [180, 400, 450, 450]
box2 = [200, 450, 425, 425]

img = np.zeros((800, 800, 3), np.uint8)  # use your image shape here or directly below

img1 = cv2.rectangle(np.zeros(img.shape), (box1[0], box1[1]), (box1[2], box1[3]), (1, 1, 1), -1) 
img2 = cv2.rectangle(np.zeros(img.shape), (box2[0], box2[1]), (box2[2], box2[3]), (1, 1, 1), -1)

jaccard_score(img1.ravel(),img2.ravel())
Abhi25t
  • 3,703
  • 3
  • 19
  • 32