确保预处理方式相同。

This commit is contained in:
2025-12-12 14:10:21 +08:00
parent 6d25343989
commit f18063e50f
2 changed files with 115 additions and 33 deletions
@@ -97,11 +97,61 @@ class COCOToSegFormerConverter:
return np.array(mask)
def _rle_to_mask(self, rle: Dict, image_size: Tuple[int, int]) -> np.ndarray:
"""
将COCO的RLE (Run-Length Encoding) 格式转换为像素级mask
RLE格式说明:
- counts: [v1, v2, v3, ...] 交替表示背景和前景的像素数量
- 从背景(0)开始,然后是前景(1),再是背景(0),依此类推
- 像素顺序:从左到右,从上到下(行优先)
Args:
rle: COCO的RLE字典,格式为 {"counts": [n1, n2, ...], "size": [height, width]}
image_size: 图像尺寸 (width, height)
Returns:
mask: 二值mask数组 (H, W),1表示目标区域,0表示背景
"""
width, height = image_size
# 获取RLE的counts
if 'counts' in rle:
counts = rle['counts']
else:
print(f" ⚠️ 警告: RLE格式不包含counts字段")
return np.zeros((height, width), dtype=np.uint8)
# 创建一维数组
mask = np.zeros(height * width, dtype=np.uint8)
current_pos = 0
current_value = 0 # 从背景开始
for count in counts:
# 如果当前是前景(1),填充mask
if current_value == 1:
mask[current_pos:current_pos + count] = 1
# 移动位置
current_pos += count
# 切换值(0 -> 1 -> 0 -> 1 ...
current_value = 1 - current_value
# 重塑为2D数组 (H, W)
mask = mask.reshape((height, width))
return mask
def _merge_annotations(self, image_id: int, image_size: Tuple[int, int]) -> np.ndarray:
"""
合并一张图像的所有标注为单一mask
由于用户标注时所有食材区域都是同一类别,我们需要将同一图像的多个标注合并
支持两种格式:
1. Polygon格式: segmentation 是列表的列表
2. RLE格式: segmentation 是包含 'counts' 字段的字典
Args:
image_id: COCO图像ID
@@ -120,11 +170,24 @@ class COCOToSegFormerConverter:
# 将所有标注合并到同一个mask
for ann in annotations:
if 'segmentation' in ann and isinstance(ann['segmentation'], list):
# 转换polygon为mask
obj_mask = self._polygon_to_mask(ann['segmentation'], image_size)
# 合并到总mask(取并集)
merged_mask = np.maximum(merged_mask, obj_mask)
if 'segmentation' not in ann:
continue
segmentation = ann['segmentation']
# 判断是RLE格式还是Polygon格式
if isinstance(segmentation, dict) and 'counts' in segmentation:
# RLE格式
obj_mask = self._rle_to_mask(segmentation, image_size)
elif isinstance(segmentation, list) and len(segmentation) > 0:
# Polygon格式
obj_mask = self._polygon_to_mask(segmentation, image_size)
else:
print(f" ⚠️ 警告: 未知的segmentation格式: {type(segmentation)}")
continue
# 合并到总mask(取并集)
merged_mask = np.maximum(merged_mask, obj_mask)
return merged_mask
@@ -247,7 +310,7 @@ def main():
"""
# ==================== 配置区 ====================
# TODO: 请根据您的实际路径修改以下三个变量
# 请根据您的实际路径修改以下三个变量
# CVAT导出的COCO标注文件(通常名为instances_default.json
COCO_JSON_PATH = "d:/MyProjects/PythonProjects/FoodClassifier/SegFormer/data/raw_coco/annotations/instances_default.json"