Add oriented_box_iou_batch function to detection.utils#1502
Add oriented_box_iou_batch function to detection.utils#1502LinasKo merged 5 commits intoroboflow:developfrom
oriented_box_iou_batch function to detection.utils#1502Conversation
|
Excellent work, @patel-zeel! I especially like the visuals. To answer your questions:
|
Thank you, @LinasKo. While making the plots, I realized that gridlines pass from the middle of a pixel, making it hard to visually count union, intersection, and IoU. Thus, I shifted the gridlines by half of the pixel size to make sure pixels overlap with the cells of the grid and not on the intersections of gridlines. It was fun working on this! Another question:
Now, coming to other points raised by you:
Yes, that makes sense! Thank you.
Given all the same values, box_detection = np.array([[0, 0], [0, 0], [0, 0], [0, 0]])
box_true = np.array([[0, 0], [0, 0], [0, 0], [0, 0]])box_detection = np.array([[1, 1], [1, 1], [1, 1], [1, 1]])
box_true = np.array([[0, 0], [0, 0], [0, 0], [0, 0]]) |
|
@LinasKo, this is a gentle ping to let you know that I can make the desired changes before you again review this PR. Feel free to let me know whenever you take a look. |
|
Hi @patel-zeel, I have it in my sights - I'll 100% include it before the new release, and very likely in the next few days. Apologies for the long wait! |
|
Thank you for the quick response, @LinasKo. No worries at all. |
|
Hi @patel-zeel, here's my feedback:
Here's the Colab I worked with. |
|
Hi @LinasKo, thank you for the feedback.
Yes, that seems logically correct, but the current implementation of To add more context, the area of the mask depends on whether we include the pixels on which the box boundary lies. However, none of those two cases will match the area formula. For example, box This brings a question: Shouldn't this match how object detection models handle bounding boxes, as in, how do they process pixels on which the box boundary lies? from supervision import polygon_to_mask
def xyxy_to_xyxyxyxy(xyxy) -> np.ndarray:
results = []
for box in xyxy:
obb_single = np.array([
(box[0], box[1]),
(box[2], box[1]),
(box[2], box[3]),
(box[0], box[3]),
])
results.append(obb_single)
return np.array(results)
xyxy = np.array([[0, 0, 0, 0]])
xyxyxyxy = xyxy_to_xyxyxyxy(xyxy)
mask = polygon_to_mask(xyxyxyxy, (3, 3))
print(mask)Output [[1. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]] |
|
Hi @patel-zeel, thank you for your thoughts. Indeed, I can see the issue. The problem preceding this discussion is that
Quick note: here we should not consider the standard where all boundary pixels are excluded. The viable options are:
Putting that aside, let's sacrifice correctness for now and focus on enabling more use cases. Areas are primarily used to compare detections of the same type, after all. I'll take over, carry out the minor doc fixes, run a few tests, and merge this in. I've also noted down that |
|
Sure, @LinasKo. It was interesting to work on this issue. I'm looking forward to seeing it in the next release. |
LinasKo
left a comment
There was a problem hiding this comment.
I've checked the code, verified the results are what we expected and built the docs. Looks good; merging!
Thank you @patel-zeel! 🤝
It is a true delight, seeing a thoughtfully made and tested PR such as yours. Especially when it reveals further flaws we can investigate to make our library even better. It has been a pleasure working with you.
|
hi @patel-zeel, kinda unrelated question |
|
Hi @MoAbbasid, you can generate these plots with the |



Description
Implemented
oriented_box_iou_batchfunction indetection.utilsas discussed with @LinasKo in #1295.No additional dependencies are required for this change.
Context
Important details for the reviewers:
polygon_to_maskfunction requiresresolution_whargument but I have bypassed it by considering a pseudo-image that covers the true and detected boxes. I am assuming that we will always pass box values in the true scale of the image size and not scaled to [0, 1].Questions for the reviewers:
box_iou_batchfunction?np.nan_to_num(ious)before returningious?Type of change
How has this change been tested, please provide a testcase or example of how you tested the change?
Thus far, I have not added any tests. I have tested the function with the following code snippet. Showing the examples and plots first followed by the code snippet:
Examples and plots
Code snippet
Any specific deployment considerations (this section is not yet edited)
For example, documentation changes, usability, usage/costs, secrets, etc.
Docs (this section is not yet edited)