Spring14th commited on
Commit
488facf
·
verified ·
1 Parent(s): 1a0c6f7

Upload json2mask.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. json2mask.py +95 -0
json2mask.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ LabelMe line 标注 → 二值掩码 PNG
3
+ ---------------------------------
4
+ 输入:172 个 JSON 文件(shape_type="line")
5
+ 输出:同名的 _mask.png(白色=弦,黑色=背景)
6
+
7
+ 用法:
8
+ python json2mask.py \
9
+ --json_dir /home/wz/Git/SAM_guqin/annotations \
10
+ --img_dir /home/wz/Git/SAM_guqin \
11
+ --out_dir /home/wz/Git/SAM_guqin/masks \
12
+ --line_width 7
13
+ """
14
+
15
+ import json
16
+ import cv2
17
+ import numpy as np
18
+ import argparse
19
+ import os
20
+ from pathlib import Path
21
+
22
+ def json_to_mask(json_path, img_h, img_w, line_width=7):
23
+ """把一个 LabelMe JSON 里所有 line 形状画成二值掩码"""
24
+ with open(json_path, "r") as f:
25
+ data = json.load(f)
26
+
27
+ mask = np.zeros((img_h, img_w), dtype=np.uint8)
28
+
29
+ for shape in data["shapes"]:
30
+ if shape["shape_type"] != "line":
31
+ continue
32
+ pts = shape["points"]
33
+ x1, y1 = int(round(pts[0][0])), int(round(pts[0][1]))
34
+ x2, y2 = int(round(pts[1][0])), int(round(pts[1][1]))
35
+ # 画线,thickness 对应弦宽(像素)
36
+ cv2.line(mask, (x1, y1), (x2, y2), 255, thickness=line_width)
37
+
38
+ # 轻微膨胀,弥补标注偏差
39
+ kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
40
+ mask = cv2.dilate(mask, kernel, iterations=1)
41
+
42
+ return mask
43
+
44
+
45
+ def main():
46
+ parser = argparse.ArgumentParser()
47
+ parser.add_argument("--json_dir", required=True, help="JSON 文件目录")
48
+ parser.add_argument("--img_dir", required=True, help="原始图像目录")
49
+ parser.add_argument("--out_dir", required=True, help="掩码输出目录")
50
+ parser.add_argument("--line_width", type=int, default=7,
51
+ help="弦线宽度(像素),默认 7")
52
+ args = parser.parse_args()
53
+
54
+ os.makedirs(args.out_dir, exist_ok=True)
55
+
56
+ json_files = sorted(Path(args.json_dir).glob("*.json"))
57
+ if not json_files:
58
+ raise FileNotFoundError(f"在 {args.json_dir} 下没有找到 JSON 文件")
59
+
60
+ print(f"共找到 {len(json_files)} 个 JSON 文件,开始转换...")
61
+
62
+ ok, skip = 0, 0
63
+ for jf in json_files:
64
+ # 读取图像尺寸(优先从 JSON 里取,避免再读图)
65
+ with open(jf) as f:
66
+ meta = json.load(f)
67
+
68
+ img_h = meta.get("imageHeight")
69
+ img_w = meta.get("imageWidth")
70
+
71
+ # JSON 里没有尺寸则从图像文件读
72
+ if not img_h or not img_w:
73
+ img_name = meta.get("imagePath", jf.stem + ".jpg")
74
+ img_path = Path(args.img_dir) / img_name
75
+ if not img_path.exists():
76
+ print(f" [SKIP] 找不到图像: {img_path}")
77
+ skip += 1
78
+ continue
79
+ img = cv2.imread(str(img_path))
80
+ img_h, img_w = img.shape[:2]
81
+
82
+ mask = json_to_mask(jf, img_h, img_w, args.line_width)
83
+
84
+ out_name = jf.stem + "_mask.png"
85
+ out_path = Path(args.out_dir) / out_name
86
+ cv2.imwrite(str(out_path), mask)
87
+ ok += 1
88
+ print(f" [{ok}/{len(json_files)}] {jf.name} → {out_name}")
89
+
90
+ print(f"\n完成!成功 {ok} 张,跳过 {skip} 张")
91
+ print(f"掩码保存在: {args.out_dir}")
92
+
93
+
94
+ if __name__ == "__main__":
95
+ main()