guqin_model / json2mask.py
Spring14th's picture
Upload json2mask.py with huggingface_hub
488facf verified
Raw
History Blame Contribute Delete
3.18 kB
"""
LabelMe line 标注 → 二值掩码 PNG
---------------------------------
输入:172 个 JSON 文件(shape_type="line")
输出:同名的 _mask.png(白色=弦,黑色=背景)
用法:
python json2mask.py \
--json_dir /home/wz/Git/SAM_guqin/annotations \
--img_dir /home/wz/Git/SAM_guqin \
--out_dir /home/wz/Git/SAM_guqin/masks \
--line_width 7
"""
import json
import cv2
import numpy as np
import argparse
import os
from pathlib import Path
def json_to_mask(json_path, img_h, img_w, line_width=7):
"""把一个 LabelMe JSON 里所有 line 形状画成二值掩码"""
with open(json_path, "r") as f:
data = json.load(f)
mask = np.zeros((img_h, img_w), dtype=np.uint8)
for shape in data["shapes"]:
if shape["shape_type"] != "line":
continue
pts = shape["points"]
x1, y1 = int(round(pts[0][0])), int(round(pts[0][1]))
x2, y2 = int(round(pts[1][0])), int(round(pts[1][1]))
# 画线,thickness 对应弦宽(像素)
cv2.line(mask, (x1, y1), (x2, y2), 255, thickness=line_width)
# 轻微膨胀,弥补标注偏差
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
mask = cv2.dilate(mask, kernel, iterations=1)
return mask
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--json_dir", required=True, help="JSON 文件目录")
parser.add_argument("--img_dir", required=True, help="原始图像目录")
parser.add_argument("--out_dir", required=True, help="掩码输出目录")
parser.add_argument("--line_width", type=int, default=7,
help="弦线宽度(像素),默认 7")
args = parser.parse_args()
os.makedirs(args.out_dir, exist_ok=True)
json_files = sorted(Path(args.json_dir).glob("*.json"))
if not json_files:
raise FileNotFoundError(f"在 {args.json_dir} 下没有找到 JSON 文件")
print(f"共找到 {len(json_files)} 个 JSON 文件,开始转换...")
ok, skip = 0, 0
for jf in json_files:
# 读取图像尺寸(优先从 JSON 里取,避免再读图)
with open(jf) as f:
meta = json.load(f)
img_h = meta.get("imageHeight")
img_w = meta.get("imageWidth")
# JSON 里没有尺寸则从图像文件读
if not img_h or not img_w:
img_name = meta.get("imagePath", jf.stem + ".jpg")
img_path = Path(args.img_dir) / img_name
if not img_path.exists():
print(f" [SKIP] 找不到图像: {img_path}")
skip += 1
continue
img = cv2.imread(str(img_path))
img_h, img_w = img.shape[:2]
mask = json_to_mask(jf, img_h, img_w, args.line_width)
out_name = jf.stem + "_mask.png"
out_path = Path(args.out_dir) / out_name
cv2.imwrite(str(out_path), mask)
ok += 1
print(f" [{ok}/{len(json_files)}] {jf.name}{out_name}")
print(f"\n完成!成功 {ok} 张,跳过 {skip} 张")
print(f"掩码保存在: {args.out_dir}")
if __name__ == "__main__":
main()