Support for IOS Matching Metric. Introduced the `mask_non_max_merge` function for handling non-maximum merging of masks
Description
When I used the yolo11-seg model for slice inference, I found that the merging did not work well. After analysis, it is found that for slender objects, its mask area only accounts for a small part, and the box area may be very large, so it is necessary to use mask for iou calculation.
When I implemented the mask_non_max_merge function, I found that the merge effect was still not satisfactory, as shown in the figure:
I found that the sahi library implemented the non-maximum merge algorithm of the IOS version, so I made changes to the code.
Type of change
Please delete options that are not relevant.
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] This change requires a documentation update
How has this change been tested, please provide a testcase or example of how you tested the change?
import cv2
import numpy as np
from PIL import Image
from ultralytics import YOLO
import supervision as sv
model = YOLO("yolon11-seg.pt")
image = cv2.imread(<your_image_path>)
def callback(image_slice: np.ndarray) -> sv.Detections:
results = model(image_slice)[0]
return sv.Detections.from_ultralytics(results)
# slicer = sv.InferenceSlicer(callback=callback, slice_wh=(960, 960), overlap_ratio_wh=None, overlap_wh=(50, 50), overlap_filter="non_max_merge", iou_threshold=0.1, match_metric="IOU")
slicer = sv.InferenceSlicer(callback=callback, slice_wh=(960, 960), overlap_ratio_wh=None, overlap_wh=(50, 50), overlap_filter="non_max_merge", iou_threshold=0.1, match_metric="IOS")
# slicer = sv.InferenceSlicer(callback=callback, slice_wh=(960, 960), overlap_ratio_wh=None, overlap_wh=(50, 50), overlap_filter="non_max_suppression", iou_threshold=0.1, match_metric="IOU")
# slicer = sv.InferenceSlicer(callback=callback, slice_wh=(960, 960), overlap_ratio_wh=None, overlap_wh=(50, 50), overlap_filter="non_max_suppression", iou_threshold=0.1, match_metric="IOS")
detections = slicer(image)
box_annotator = sv.BoxAnnotator()
mask_annotator = sv.MaskAnnotator()
label_annotator = sv.LabelAnnotator()
labels = [f"{class_name} {confidence:.2f}" for class_name, confidence in zip(detections["class_name"], detections.confidence)]
annotated_image = box_annotator.annotate(scene=image, detections=detections)
annotated_image = mask_annotator.annotate(scene=annotated_image, detections=detections)
annotated_image = label_annotator.annotate(scene=annotated_image, detections=detections, labels=labels)
Image.fromarray(annotated_image[..., ::-1]).save("test.jpg")
Any specific deployment considerations
For example, documentation changes, usability, usage/costs, secrets, etc.
Docs
- [ ] Docs updated? What were the changes:
Hi @SunHao-AI 👋🏻 thank you so much for your interest in supervision. This looks like a useful feature. I will try to get back to you with a PR review as soon as possible.
Check out this pull request on ![]()
See visual diffs & provide feedback on Jupyter Notebooks.
Powered by ReviewNB
Hi @SunHao-AI, can you please resolve the conflicts in this PR?
Hi @SunHao-AI are you on LinkedIn or X? I'd like to tag / mention you in supervision-0.26.0 release post.
Thank you. My X account is colorful_hao.