Skip to content

Commit 10ef3b3

Browse files
committed
feat: add to convert the circle to rect of lableme(#16)
1 parent cda84de commit 10ef3b3

File tree

6 files changed

+312
-135
lines changed

6 files changed

+312
-135
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ A tool for object detection and image segmentation dataset format conversion.
2323
Supports conversion between labelme tool annotated data, labelImg tool annotated data, YOLO, PubLayNet and COCO data set formats.
2424

2525
## Supported conversions
26+
2627
```mermaid
2728
flowchart LR
2829
@@ -40,19 +41,22 @@ H --> J
4041
```
4142

4243
## Installation
44+
4345
```bash
4446
pip install label_convert
4547
```
4648

4749
## Documentation
50+
4851
Full documentation can be found on [docs](https://rapidai.github.io/LabelConvert/docs) in Chinese.
4952

5053
## Contributing
54+
5155
Pull requests are welcome. For major changes, please open an issue first
5256
to discuss what you would like to change.
5357

5458
Please make sure to update tests as appropriate.
5559

56-
5760
## License
61+
5862
[Apache 2.0](https://choosealicense.com/licenses/apache-2.0/)

label_convert/labelme_to_coco.py

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@
33
# @Contact: [email protected]
44
import argparse
55
import json
6+
import math
67
import random
78
import shutil
89
import time
910
from pathlib import Path
10-
from typing import List, Union
11+
from typing import List, Tuple, Union
1112

1213
import cv2
1314
import numpy as np
1415
from tqdm import tqdm
1516

1617
ValueType = Union[str, Path, None]
17-
RECTANGLE = "rectangle"
18-
POLYGON = "polygon"
18+
RECTANGLE: str = "rectangle"
19+
POLYGON: str = "polygon"
20+
CIRCLE: str = "circle"
1921

2022

2123
class LabelmeToCOCO:
@@ -64,9 +66,7 @@ def __init__(
6466

6567
self.categories = self._get_category()
6668

67-
def __call__(
68-
self,
69-
):
69+
def __call__(self):
7070
img_list = self.get_img_list()
7171
if not img_list:
7272
raise ValueError(f"{self.data_dir} is empty!")
@@ -146,9 +146,7 @@ def _init_json(self):
146146
}
147147
return annotation_info
148148

149-
def _get_category(
150-
self,
151-
):
149+
def _get_category(self):
152150
json_list = Path(self.data_dir).glob("*.json")
153151
all_categories = []
154152
for json_path in json_list:
@@ -198,9 +196,9 @@ def generate_json(self, img_list, save_dir):
198196
anno_list = []
199197
for shape in shapes:
200198
shape_type = shape.get("shape_type")
201-
if shape_type not in [RECTANGLE, POLYGON]:
199+
if shape_type not in [RECTANGLE, POLYGON, CIRCLE]:
202200
print(
203-
f"Current shape type is {shape_type}, not between {RECTANGLE} and {POLYGON}, skip"
201+
f"Current shape type is {shape_type}, not between {RECTANGLE}, {CIRCLE} and {POLYGON}, skip"
204202
)
205203
continue
206204

@@ -209,17 +207,25 @@ def generate_json(self, img_list, save_dir):
209207
points = np.array(shape.get("points"))
210208

211209
if shape_type == RECTANGLE:
212-
seg_points = [np.ravel(points, order="C").tolist()]
213-
214210
x0, y0 = np.min(points, axis=0)
215211
x1, y1 = np.max(points, axis=0)
216-
w, h = x1 - x1, y1 - y0
212+
seg_points = [[x0, y0, x1, y0, x1, y1, x0, y1]]
213+
214+
w, h = x1 - x0, y1 - y0
217215
bbox_points = [x0, y0, w, h]
218216
area = w * h
219-
220217
elif shape_type == POLYGON:
221218
seg_points = points.tolist()
222219
bbox_points, area = self.cvt_poly_to_rect(img_h, img_w, points)
220+
elif shape_type == CIRCLE:
221+
circle_center, radius_point = points.tolist()
222+
x0, y0, x1, y1 = self.cvt_circle_to_rect(
223+
circle_center, radius_point
224+
)
225+
seg_points = [[x0, y0, x1, y0, x1, y1, x0, y1]]
226+
w, h = x1 - x0, y1 - y0
227+
bbox_points = [x0, y0, w, h]
228+
area = w * h
223229
else:
224230
print(f"Current {shape_type} is not supported!")
225231
continue
@@ -300,13 +306,31 @@ def get_mini_boxes(contour) -> List[int]:
300306
box_h = right_bottom[1] - left_top[1]
301307
return left_top + [box_w, box_h]
302308

309+
@staticmethod
310+
def cvt_circle_to_rect(circle_center: float, radius_point: float) -> Tuple[float]:
311+
"""
312+
根据圆心和圆上一点计算正方形边界框的左上角和右下角坐标。
313+
modified from https://blog.csdn.net/jacke121/article/details/137387901
314+
"""
315+
# 计算半径
316+
radius = math.sqrt(
317+
(circle_center[0] - radius_point[0]) ** 2
318+
+ (circle_center[1] - radius_point[1]) ** 2
319+
)
320+
321+
# 计算正方形边界框的左上角和右下角坐标
322+
x0, y0 = circle_center[0] - radius, circle_center[1] - radius
323+
x1, y1 = circle_center[0] + radius, circle_center[1] + radius
324+
325+
return x0, y0, x1, y1
326+
303327

304328
def main():
305329
parser = argparse.ArgumentParser("Datasets converter from labelme to COCO")
306330
parser.add_argument(
307331
"--data_dir",
308332
type=str,
309-
default="/Users/joshuawang/projects/_self/LabelConvert/data",
333+
default="/Users/jiahuawang/projects/LabelConvert/tests/test_files/labelme_dataset",
310334
)
311335
parser.add_argument("--save_dir", type=str, default=None)
312336
parser.add_argument("--val_ratio", type=float, default=0.2)

setup.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def get_readme() -> str:
3434
except ValueError:
3535
latest_version = "0.0.1"
3636

37-
VERSION_NUM = obtainer.version_add_one(latest_version)
37+
VERSION_NUM = obtainer.version_add_one(latest_version, add_patch=True)
3838

3939
# 优先提取commit message中的语义化版本号,如无,则自动加1
4040
if len(sys.argv) > 2:
@@ -70,8 +70,9 @@ def get_readme() -> str:
7070
"Programming Language :: Python :: 3.9",
7171
"Programming Language :: Python :: 3.10",
7272
"Programming Language :: Python :: 3.11",
73+
"Programming Language :: Python :: 3.12",
7374
],
74-
python_requires=">=3.6,<3.12",
75+
python_requires=">=3.6,<3.13",
7576
entry_points={
7677
"console_scripts": [
7778
f"coco_to_labelImg={MODULE_NAME}.coco_to_labelImg:main",

tests/test_files/labelme_dataset/4645_8.json

Lines changed: 38 additions & 2 deletions
Large diffs are not rendered by default.

tests/test_files/labelme_dataset/val_0001.json

Lines changed: 99 additions & 47 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)