MMsegmentaion自定义数据集运行出错AssertionError: failed to load image

问题

我的数据集中图像是TIF格式,4通道,想用mmsegmentation模型跑一下看看效果,按照官方手册里的方法自定义完数据集后,运行出错,错误截图如下。
MMsegmentaion自定义数据集运行出错AssertionError: failed to load image_第1张图片

解决

1.错误原因

通过上面的截图,发现错误出在红色框框中的位置,读取的img为None,这显然是不正常的,进入loading.py中,打上断点调试,发现在if判断时执行的是红框的位置,于是把红框位置的代码单独拿出来执行,
MMsegmentaion自定义数据集运行出错AssertionError: failed to load image_第2张图片
拿出来执行的代码如下

import mmcv
from mmengine import fileio

tif_path = r"D:\file\dataset\sea-land-segmentation\img_dir/train\row111col1.tif"
jpg_path = r"D:\file\dataset\dataset\WHDLD\Images\wh0001.jpg"
img_bytes = fileio.get(tif_path)
img = mmcv.imfrombytes(img_bytes,backend="cv2")
print(img)

backend=cv2是打断点调试时看到self.imdecode_backend是cv2
当输入图像为tif时,img为None,当输入图像为jpg时,img为[256,256,3],结果正常,因此猜想可能是backend参数出错,进入mmcv.infrombytes函数中查看:

def imfrombytes(content: bytes,
                flag: str = 'color',
                channel_order: str = 'bgr',
                backend: Optional[str] = None) -> np.ndarray:
    """Read an image from bytes.

    Args:
        content (bytes): Image bytes got from files or other streams.
        flag (str): Same as :func:`imread`.
        channel_order (str): The channel order of the output, candidates
            are 'bgr' and 'rgb'. Default to 'bgr'.
        backend (str | None): The image decoding backend type. Options are
            `cv2`, `pillow`, `turbojpeg`, `tifffile`, `None`. If backend is
            None, the global imread_backend specified by ``mmcv.use_backend()``
            will be used. Default: None.

    Returns:
        ndarray: Loaded image array.

    Examples:
        >>> img_path = '/path/to/img.jpg'
        >>> with open(img_path, 'rb') as f:
        >>>     img_buff = f.read()
        >>> img = mmcv.imfrombytes(img_buff)
        >>> img = mmcv.imfrombytes(img_buff, flag='color', channel_order='rgb')
        >>> img = mmcv.imfrombytes(img_buff, backend='pillow')
        >>> img = mmcv.imfrombytes(img_buff, backend='cv2')
    """

    if backend is None:
        backend = imread_backend
    if backend not in supported_backends:
        raise ValueError(
            f'backend: {backend} is not supported. Supported '
            "backends are 'cv2', 'turbojpeg', 'pillow', 'tifffile'")
    if backend == 'turbojpeg':
        img = jpeg.decode(  # type: ignore
            content, _jpegflag(flag, channel_order))
        if img.shape[-1] == 1:
            img = img[:, :, 0]
        return img
    elif backend == 'pillow':
        with io.BytesIO(content) as buff:
            img = Image.open(buff)
            img = _pillow2array(img, flag, channel_order)
        return img
    elif backend == 'tifffile':
        with io.BytesIO(content) as buff:
            img = tifffile.imread(buff)
        return img
    else:
        img_np = np.frombuffer(content, np.uint8)
        flag = imread_flags[flag] if is_str(flag) else flag
        img = cv2.imdecode(img_np, flag)
        if flag == IMREAD_COLOR and channel_order == 'rgb':
            cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img)
        return img

backends有cv2,turbojpeg,pillow,tifffile四种类型
使用pillow类型读取TIF图像时,可以成功读取,但是读取的结果只有三个通道
使用tifffile类型读取TIF图像,可以成功读取,结果正常。

2. 解决

读取图像的代码在loading.py中,可以看到self.imdecode_backend的默认值为cv2,那么在那里能修改imdecode_backend的值为tifffile呢

    def __init__(self,
                 to_float32: bool = False,
                 color_type: str = 'color',
                 imdecode_backend: str = 'cv2',
                 file_client_args: Optional[dict] = None,
                 ignore_empty: bool = False,
                 *,
                 backend_args: Optional[dict] = None) -> None:
        self.ignore_empty = ignore_empty
        self.to_float32 = to_float32
        self.color_type = color_type
        self.imdecode_backend = imdecode_backend

        self.file_client_args: Optional[dict] = None
        self.backend_args: Optional[dict] = None

imdecode_backend为下面截图中类的一个变量,全局搜索这个类名可以看到
MMsegmentaion自定义数据集运行出错AssertionError: failed to load image_第3张图片
而LoadImageFromFile是我们数据集配置文件中pipeline的一条设置,所以在下图中修改下参数就行了
MMsegmentaion自定义数据集运行出错AssertionError: failed to load image_第4张图片
注意
mmsegmentation定义的数据处理的类不一定适合4通道的图像,比如我修改imdecode_backend参数后运行在PhotoMetricDistortion和PackSegInputs就发生了错误,然后我自定义了PackTifSegInputs来取代PackSegInputs并注释掉PhotoMetricDistortion。

你可能感兴趣的:(MMsegmentation,python,人工智能)