mirror of
https://github.com/THU-MIG/yolov10.git
synced 2025-05-23 21:44:22 +08:00
Bounding Box to OBB conversion (#7572)
Co-authored-by: UltralyticsAssistant <web@ultralytics.com> Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> Co-authored-by: Laughing <61612323+Laughing-q@users.noreply.github.com> Co-authored-by: Laughing-q <1185102784@qq.com>
This commit is contained in:
parent
9dbfff4002
commit
cb72761a3b
@ -474,3 +474,64 @@ def merge_multi_segment(segments):
|
|||||||
nidx = abs(idx[1] - idx[0])
|
nidx = abs(idx[1] - idx[0])
|
||||||
s.append(segments[i][nidx:])
|
s.append(segments[i][nidx:])
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def yolo_bbox2segment(im_dir, save_dir=None, sam_model="sam_b.pt"):
|
||||||
|
"""
|
||||||
|
Converts existing object detection dataset (bounding boxes) to segmentation dataset or oriented bounding box (OBB)
|
||||||
|
in YOLO format. Generates segmentation data using SAM auto-annotator as needed.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
im_dir (str | Path): Path to image directory to convert.
|
||||||
|
save_dir (str | Path): Path to save the generated labels, labels will be saved
|
||||||
|
into `labels-segment` in the same directory level of `im_dir` if save_dir is None. Default: None.
|
||||||
|
sam_model (str): Segmentation model to use for intermediate segmentation data; optional.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
The input directory structure assumed for dataset:
|
||||||
|
- im_dir
|
||||||
|
├─ 001.jpg
|
||||||
|
├─ ..
|
||||||
|
├─ NNN.jpg
|
||||||
|
- labels
|
||||||
|
├─ 001.txt
|
||||||
|
├─ ..
|
||||||
|
├─ NNN.txt
|
||||||
|
"""
|
||||||
|
from ultralytics.data import YOLODataset
|
||||||
|
from ultralytics.utils.ops import xywh2xyxy
|
||||||
|
from ultralytics.utils import LOGGER
|
||||||
|
from ultralytics import SAM
|
||||||
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
# NOTE: add placeholder to pass class index check
|
||||||
|
dataset = YOLODataset(im_dir, data=dict(names=list(range(1000))))
|
||||||
|
if len(dataset.labels[0]["segments"]) > 0: # if it's segment data
|
||||||
|
LOGGER.info("Segmentation labels detected, no need to generate new ones!")
|
||||||
|
return
|
||||||
|
|
||||||
|
LOGGER.info("Detection labels detected, generating segment labels by SAM model!")
|
||||||
|
sam_model = SAM(sam_model)
|
||||||
|
for l in tqdm(dataset.labels, total=len(dataset.labels), desc="Generating segment labels"):
|
||||||
|
h, w = l["shape"]
|
||||||
|
boxes = l["bboxes"]
|
||||||
|
boxes[:, [0, 2]] *= w
|
||||||
|
boxes[:, [1, 3]] *= h
|
||||||
|
im = cv2.imread(l["im_file"])
|
||||||
|
sam_results = sam_model(im, bboxes=xywh2xyxy(boxes), verbose=False, save=False)
|
||||||
|
l["segments"] = sam_results[0].masks.xyn
|
||||||
|
|
||||||
|
save_dir = Path(save_dir) if save_dir else Path(im_dir).parent / "labels-segment"
|
||||||
|
save_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
for l in dataset.labels:
|
||||||
|
texts = []
|
||||||
|
lb_name = Path(l["im_file"]).with_suffix(".txt").name
|
||||||
|
txt_file = save_dir / lb_name
|
||||||
|
cls = l["cls"]
|
||||||
|
for i, s in enumerate(l["segments"]):
|
||||||
|
line = (int(cls[i]), *s.reshape(-1))
|
||||||
|
texts.append(("%g " * len(line)).rstrip() % line)
|
||||||
|
if texts:
|
||||||
|
with open(txt_file, "a") as f:
|
||||||
|
f.writelines(text + "\n" for text in texts)
|
||||||
|
LOGGER.info(f"Generated segment labels saved in {save_dir}")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user