You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

U-Net训练用JSON转Mask图像异常:仅生成细线问题修复求助

问题描述

需要将Labelme导出的JSON标注数据转换为U-Net训练用的Mask图像,使用一段Python代码后出现异常:首次运行仅部分Mask生成正常,其余仅呈现细线;再次运行后所有Mask都只剩细线。

原代码

import json
import numpy as np
import cv2
import os

# Path to the folder containing JSON files
json_folder = os.path.expanduser('~/Desktop/jeson')  # Folder with JSON files
# Path to the folder for saving mask images
mask_folder = os.path.expanduser('~/Desktop/masks')  # Folder to save masks

# Ensure the folder for saving masks exists
os.makedirs(mask_folder, exist_ok=True)

# List all JSON files in the folder
for filename in os.listdir(json_folder):
    if filename.endswith('.json'):
        json_file = os.path.join(json_folder, filename)

        # Load data from the JSON file
        with open(json_file) as f:
            data = json.load(f)

        # Create an empty mask
        mask = np.zeros((data['imageHeight'], data['imageWidth']), dtype=np.uint8)

        # Add regions to the mask
        for shape in data['shapes']:
            points = np.array(shape['points'], dtype=np.int32)
            if len(points) > 0:
                # Fill the area defined by the points with white color
                cv2.fillPoly(mask, [points], 49)

        # Save the mask as a PNG image using OpenCV
        mask_filename = os.path.splitext(filename)[0] + '_mask.png'
        cv2.imwrite(os.path.join(mask_folder, mask_filename), mask)

print("Conversion completed, and mask images have been saved in the 'masks' folder!")

问题原因

  1. 坐标精度丢失:Labelme导出的标注坐标是浮点数,直接强制转换为int32会截断小数部分,导致多边形顶点错位,无法形成可填充的闭合区域,cv2.fillPoly只能画出边缘细线。
  2. 多边形未闭合:部分标注的多边形首尾点未重合,cv2.fillPoly对非闭合多边形的填充行为不稳定,容易出现填充失败。
  3. 无效形状处理:代码未过滤顶点数不足3的无效形状,这类形状无法形成多边形,自然无法填充。

修复方案

修正后的代码

import json
import numpy as np
import cv2
import os

json_folder = os.path.expanduser('~/Desktop/jeson')
mask_folder = os.path.expanduser('~/Desktop/masks')

os.makedirs(mask_folder, exist_ok=True)

for filename in os.listdir(json_folder):
    if filename.endswith('.json'):
        json_file = os.path.join(json_folder, filename)
        with open(json_file) as f:
            data = json.load(f)

        # 创建空掩码,匹配原图像尺寸
        mask = np.zeros((data['imageHeight'], data['imageWidth']), dtype=np.uint8)

        for shape in data['shapes']:
            # 对浮点坐标四舍五入后转int,避免精度丢失导致顶点偏移
            points = np.round(np.array(shape['points'])).astype(np.int32)
            
            # 确保多边形闭合:首尾点不重合时,补全首点到末尾
            if len(points) >= 3 and not np.array_equal(points[0], points[-1]):
                points = np.vstack([points, points[0]])
            
            # 仅处理有效多边形(至少3个顶点)
            if len(points) >= 3:
                # 填充多边形区域,这里用255(白色),若需49可直接替换
                cv2.fillPoly(mask, [points], 255)

        # 无损保存PNG掩码
        mask_filename = os.path.splitext(filename)[0] + '_mask.png'
        cv2.imwrite(os.path.join(mask_folder, mask_filename), mask, [cv2.IMWRITE_PNG_COMPRESSION, 0])

print("转换完成,掩码已保存到masks文件夹!")

关键修改点

  • 坐标精度修正:用np.round()处理浮点坐标后再转整数,避免截断导致的顶点错位。
  • 多边形闭合处理:自动补全首尾点,确保多边形严格闭合,保证填充功能正常工作。
  • 无效形状过滤:只处理顶点数≥3的有效多边形,排除无法填充的无效标注。
  • 保存优化:添加PNG无损压缩参数,避免图像保存时的质量损失;填充值默认用255(U-Net训练通用的掩码白色值),需保留49可直接修改。

内容的提问来源于stack exchange,提问作者user25377348

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 17:19:53