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

Runlength编码掩码与解码后掩码不一致问题排查求助

问题排查与修复

针对你在Severstal钢铁异常检测任务中遇到的增强后掩码编解码不一致问题,核心问题出在形状逻辑不匹配和掩码数值类型干扰这两个点,以下是具体排查和修复方案:

1. 核心问题分析

形状与转置的不匹配

你的rle_to_mask函数最终返回mask.reshape(shape).T,也就是将(width, height)的数组转置为(height, width)(即默认的(256,1600)),但mask_to_rle函数没有对应处理形状的逻辑,再加上测试代码中额外的cv2.resize操作,彻底打乱了编解码的形状对应关系:

  • 增强后的transformed_mask形状应为(256,1600)
  • 你执行mask=cv2.resize(mask,(1600,256))将其改为(1600,256),此时mask_to_rle处理的是变形后的掩码,而rle_to_mask(lre)默认返回(256,1600)的掩码,自然内容和形状都无法匹配。

掩码数值类型的潜在干扰

数据增强后的掩码可能是浮点型(比如0.0/1.0),如果增强过程引入了模糊、插值导致的非0非1中间值,np.where(padded[1:] != padded[:-1])会错误识别更多边界,导致RLE编码错误。

2. 修复方案

调整mask_to_rle函数,统一形状逻辑

让mask_to_rle接收形状参数,确保编码的展平顺序和rle_to_mask的还原顺序完全对应:

import numpy as np

def mask_to_rle(mask, shape=(1600, 256)):
    """
    params:  mask - numpy array (height, width),即(256,1600)
             shape - (width, height),对应原始图像尺寸(1600,256)
    returns: run-length encoding string (pairs of start & length of encoding)
    """
    # 先转置为(width, height),和rle_to_mask的还原逻辑对齐
    mask_transposed = mask.T
    flat = mask_transposed.flatten()
    
    # 强制转换为0/1整数,避免浮点精度问题
    flat = flat.astype(np.uint8)
    
    padded = np.concatenate([[0], flat, [0]])
    runs = np.where(padded[1:] != padded[:-1])[0] 
    runs += 1  # 转换为从1开始的像素编号

    runs[1::2] -= runs[0::2]
 
    return ' '.join(str(x) for x in runs)

修正测试代码中的无效操作

去掉打乱形状的cv2.resize,确保编解码使用一致的形状:

img, mask = augmentation_test(train_df)
# 直接对增强后的掩码执行编解码
lre = mask_to_rle(mask)
lree = rle_to_mask(lre)
# 验证一致性
print(np.array_equal(mask, lree))  # 正常应返回True

# 可视化对比
plt.subplot(121)
plt.imshow(mask)
plt.title('原增强掩码')
plt.subplot(122)
plt.imshow(lree)
plt.title('解码后掩码')
plt.show()

增强后掩码的二值化处理

在augmentation_test中添加二值化步骤,确保掩码只有0和1两种值:

import cv2
import pandas as pd
import os
from albumentations import transform

def augmentation_test(dataframe:pd.DataFrame):
    record = dataframe.loc[np.random.randint(10)]
    image = cv2.imread(os.path.join("./train_images", record['ImageId']), 0)
    image = cv2.resize(image, (1600, 256))
    mask = rle_to_mask(record['EncodedPixels'])
    transformed = transform(image=image, mask=mask)
    transformed_image = transformed['image']
    # 二值化掩码,避免增强带来的中间值
    transformed_mask = (transformed['mask'] > 0.5).astype(np.uint8)
    return transformed_image, transformed_mask

3. 验证逻辑

  1. 确认rle_to_mask返回的掩码形状是(256,1600),与mask_to_rle接收的输入形状一致
  2. 增强后的掩码必须经过二值化处理,杜绝非0非1的中间值
  3. 编解码过程中不要随意修改掩码形状,保持形状对应关系

内容的提问来源于stack exchange,提问作者SANJAY. R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 15:30:05