如何基于给定标注值在图像上绘制分割掩码与边界框
基于COCO格式JSON标注绘制分割掩码与边界框的实现方法
你提供的标注属于标准COCO实例分割标注格式,可通过OpenCV+Numpy快速实现标注可视化,具体实现如下:
前置依赖
需要先安装依赖库,执行以下安装命令:pip install opencv-python numpy
如果标注存在RLE格式的分割(iscrowd=1的场景),还需安装pycocotools:pip install pycocotools
完整实现代码
import json import cv2 import numpy as np from collections import defaultdict # 配置项,根据自身实际路径修改 ANNOTATION_FILE = "你的标注文件路径.json" IMAGE_FOLDER = "存放所有图像的文件夹路径" MASK_TRANSPARENCY = 0.5 # 掩码透明度,取值0-1,越大越不透明 # 类别与颜色映射(OpenCV默认BGR色彩顺序) CATEGORY_COLOR = { 1: (0, 0, 255), # 类别1对应红色 2: (0, 255, 0), # 类别2对应绿色 # 可自行扩展更多类别 } # 加载所有标注并按image_id分组 with open(ANNOTATION_FILE, "r", encoding="utf-8") as f: all_annotations = json.load(f) anno_group = defaultdict(list) for anno in all_annotations: anno_group[anno["image_id"]].append(anno) # 逐图处理标注绘制 for img_id, anno_list in anno_group.items(): # 读取对应图像,此处假设图像命名为{image_id}.jpg,可根据实际命名规则修改 img_path = f"{IMAGE_FOLDER}/{img_id}.jpg" origin_img = cv2.imread(img_path) if origin_img is None: print(f"图像{img_path}读取失败,已跳过") continue # 新建掩码层用于半透明叠加,避免直接修改原图 mask_layer = origin_img.copy() for anno in anno_list: current_color = CATEGORY_COLOR.get(anno["category_id"], (255, 0, 0)) # 绘制边界框 x_min, y_min, w, h = anno["bbox"] x_max = int(x_min + w) y_max = int(y_min + h) cv2.rectangle(origin_img, (int(x_min), int(y_min)), (x_max, y_max), current_color, thickness=2) # 绘制分割掩码 seg_point_list = anno["segmentation"] for seg in seg_point_list: np_seg = np.array(seg, dtype=np.int32).reshape((-1, 1, 2)) cv2.fillPoly(mask_layer, [np_seg], current_color) # 叠加掩码和原图 cv2.addWeighted(mask_layer, MASK_TRANSPARENCY, origin_img, 1 - MASK_TRANSPARENCY, 0, origin_img) # 保存结果,也可调用cv2.imshow直接展示 cv2.imwrite(f"./drawed_{img_id}.jpg", origin_img)
注意事项
- 若你的图像命名规则不是
{image_id}.jpg,需要自行修改代码中图像路径的拼接逻辑 - 当标注的
iscrowd字段为1时,segmentation为RLE编码格式,需调用pycocotools.mask.decode()接口解码得到掩码矩阵后再绘制 - 可通过调整
MASK_TRANSPARENCY参数修改掩码的透明程度,匹配自己的可视化需求 - 边界框的厚度可通过修改
cv2.rectangle的thickness参数调整
内容的提问来源于stack exchange,提问作者birdistheword
相关产品推荐
相关产品推荐

