Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to read images in TIFF format as a dataset. #3472

Open
o-lucky-o opened this issue Dec 12, 2023 · 5 comments
Open

How to read images in TIFF format as a dataset. #3472

o-lucky-o opened this issue Dec 12, 2023 · 5 comments

Comments

@o-lucky-o
Copy link

o-lucky-o commented Dec 12, 2023

I created a dataset called MyDataset, and the input images are (c, h, w). Since c>3, I chose a TIFF format image for my input images.

I learned from #2903 that I can use backend_ args ,this parameter is used to specify the backend for reading images, and supports Tiff format images .

I followed #2468 and mmengine.fileio.io to operate, but an error occurred, so how should I solve this problem.

File "/data/lh/miniconda3/envs/torch/lib/python3.8/site-packages/mmengine/fileio/io.py", line 97, in _get_file_backend
backend = backends[backend_name](** backend_args_bak)
KeyError: 'tifffile'

During handling of the above exception, another exception occurred:
File "/data/lh/miniconda3/envs/torch/lib/python3.8/site-packages/mmengine/registry/build_functions.py", line 144, in build_from_cfg
raise type(e)(
KeyError: "class MyDataset in mmseg/datasets/MyDataset.py: 'tifffile'"

File "/data/lh/miniconda3/envs/torch/lib/python3.8/site-packages/mmengine/registry/build_functions.py", line 144, in build_from_cfg
raise type(e)(
KeyError: 'class IterBasedTrainLoop in mmengine/runner/loops.py: "class MyDataset in mmseg/datasets/MyDataset.py: 'tifffile'"'

from mmseg.registry import DATASETS
from .basesegdataset import BaseSegDataset


@DATASETS.register_module()
class MyDataset(BaseSegDataset):
    # 类别和对应的 RGB配色
    METAINFO = {
        'classes':['blackground', 'haha']],
        'palette':[[255,255,255],[0,255,0]]
    }
    

    # 指定图像扩展名、标注扩展名
    def __init__(self,
                 img_suffix='.tiff',  # 数据集图片的后缀
                 seg_map_suffix='.png',   # 标注mask图像的后缀格式
                 reduce_zero_label=False, # 类别ID为0的类别是否需要除去
                 **kwargs) -> None:
        
        super().__init__(
                 img_suffix=img_suffix,
                 seg_map_suffix=seg_map_suffix,
                 reduce_zero_label=reduce_zero_label,
                 backend_args={'backend': 'tifffile'},
                 **kwargs)
@AI-Tianlong
Copy link
Contributor

AI-Tianlong commented Jan 4, 2024

You can change your dataset configs

train_pipeline = [
    dict(type=LoadSingleRSImagFromFile)

more details about LoadSingleRSImagFromFile in,

@TRANSFORMS.register_module()
class LoadSingleRSImageFromFile(BaseTransform):
"""Load a Remote Sensing mage from file.
Required Keys:
- img_path
Modified Keys:
- img
- img_shape
- ori_shape
Args:
to_float32 (bool): Whether to convert the loaded image to a float32
numpy array. If set to False, the loaded image is a float64 array.
Defaults to True.
"""
def __init__(self, to_float32: bool = True):
self.to_float32 = to_float32
if gdal is None:
raise RuntimeError('gdal is not installed')
def transform(self, results: Dict) -> Dict:
"""Functions to load image.
Args:
results (dict): Result dict from :obj:``mmcv.BaseDataset``.
Returns:
dict: The dict contains loaded image and meta information.
"""
filename = results['img_path']
ds = gdal.Open(filename)
if ds is None:
raise Exception(f'Unable to open file: {filename}')
img = np.einsum('ijk->jki', ds.ReadAsArray())
if self.to_float32:
img = img.astype(np.float32)
results['img'] = img
results['img_shape'] = img.shape[:2]
results['ori_shape'] = img.shape[:2]
return results
def __repr__(self):
repr_str = (f'{self.__class__.__name__}('
f'to_float32={self.to_float32})')
return repr_str

@jacksteussie
Copy link

jacksteussie commented Mar 28, 2024

Contributor

How is this different than using imdecode_backend=tifffile in the 'LoadAnnotation' or 'LoadImageFromFile' transformations?

@AI-Tianlong
Copy link
Contributor

AI-Tianlong commented Mar 28, 2024

Contributor

How is this different than using imdecode_backend=tifffile in the 'LoadAnnotation' or 'LoadImageFromFile' transformations?

I'm not sure whether backends tifffile support, but if you want to deal with multi-channel remote sensing images, I am more recommend LoadSingleRSImageFromFile, it is based on the gdal backend. You can use conda install gdal to install GDAL, it's works really well.

@AI-Tianlong
Copy link
Contributor

You can change your dataset configs

train_pipeline = [
    dict(type=LoadSingleRSImagFromFile)

more details about LoadSingleRSImagFromFile in,

@TRANSFORMS.register_module()
class LoadSingleRSImageFromFile(BaseTransform):
"""Load a Remote Sensing mage from file.
Required Keys:
- img_path
Modified Keys:
- img
- img_shape
- ori_shape
Args:
to_float32 (bool): Whether to convert the loaded image to a float32
numpy array. If set to False, the loaded image is a float64 array.
Defaults to True.
"""
def __init__(self, to_float32: bool = True):
self.to_float32 = to_float32
if gdal is None:
raise RuntimeError('gdal is not installed')
def transform(self, results: Dict) -> Dict:
"""Functions to load image.
Args:
results (dict): Result dict from :obj:``mmcv.BaseDataset``.
Returns:
dict: The dict contains loaded image and meta information.
"""
filename = results['img_path']
ds = gdal.Open(filename)
if ds is None:
raise Exception(f'Unable to open file: {filename}')
img = np.einsum('ijk->jki', ds.ReadAsArray())
if self.to_float32:
img = img.astype(np.float32)
results['img'] = img
results['img_shape'] = img.shape[:2]
results['ori_shape'] = img.shape[:2]
return results
def __repr__(self):
repr_str = (f'{self.__class__.__name__}('
f'to_float32={self.to_float32})')
return repr_str

@AI-Tianlong I tried this but got "KeyError: 'LoadSingleRSImagFromFile is not in the mmseg::transform registry. Please check whether the value of LoadSingleRSImagFromFile is correct or it was registered as expected. More details can be found at https://mmengine.readthedocs.io/en/latest/advanced_tutorials/config.html#import-the-custom-module'"

However I can find this function in the mmsegmentation/mmseg/datasets/transforms/loading.py file

my packages` version mmcv 2.1.0 pypi_0 pypi mmengine 0.10.4 pypi_0 pypi mmsegmentation 1.2.2 pypi_0 pypi

Hello,我猜老铁是个Chinese,我用中文说可能表达更清楚。
我这个例子

train_pipeline = [
    dict(type=LoadSingleRSImagFromFile)

是用的 new config,所以没有加引号。
如果你用的是正常的config的话

train_pipeline = [
    dict(type='LoadSingleRSImagFromFile')

要这么写,理论上不会出现这个错误。
你可以再检查一下你的

'RandomRotFlip', 'Albu', 'LoadSingleRSImageFromFile', 'ConcatCDInput',

这个位置,是否有 LoadSingleRSImagFromFile

@crosage
Copy link

crosage commented Aug 1, 2024

You can change your dataset configs

train_pipeline = [
    dict(type=LoadSingleRSImagFromFile)

more details about LoadSingleRSImagFromFile in,

@TRANSFORMS.register_module()
class LoadSingleRSImageFromFile(BaseTransform):
"""Load a Remote Sensing mage from file.
Required Keys:
- img_path
Modified Keys:
- img
- img_shape
- ori_shape
Args:
to_float32 (bool): Whether to convert the loaded image to a float32
numpy array. If set to False, the loaded image is a float64 array.
Defaults to True.
"""
def __init__(self, to_float32: bool = True):
self.to_float32 = to_float32
if gdal is None:
raise RuntimeError('gdal is not installed')
def transform(self, results: Dict) -> Dict:
"""Functions to load image.
Args:
results (dict): Result dict from :obj:``mmcv.BaseDataset``.
Returns:
dict: The dict contains loaded image and meta information.
"""
filename = results['img_path']
ds = gdal.Open(filename)
if ds is None:
raise Exception(f'Unable to open file: {filename}')
img = np.einsum('ijk->jki', ds.ReadAsArray())
if self.to_float32:
img = img.astype(np.float32)
results['img'] = img
results['img_shape'] = img.shape[:2]
results['ori_shape'] = img.shape[:2]
return results
def __repr__(self):
repr_str = (f'{self.__class__.__name__}('
f'to_float32={self.to_float32})')
return repr_str

@AI-Tianlong I tried this but got "KeyError: 'LoadSingleRSImagFromFile is not in the mmseg::transform registry. Please check whether the value of LoadSingleRSImagFromFile is correct or it was registered as expected. More details can be found at https://mmengine.readthedocs.io/en/latest/advanced_tutorials/config.html#import-the-custom-module'"
However I can find this function in the mmsegmentation/mmseg/datasets/transforms/loading.py file
my packages` version mmcv 2.1.0 pypi_0 pypi mmengine 0.10.4 pypi_0 pypi mmsegmentation 1.2.2 pypi_0 pypi

Hello,我猜老铁是个Chinese,我用中文说可能表达更清楚。 我这个例子

train_pipeline = [
    dict(type=LoadSingleRSImagFromFile)

是用的 new config,所以没有加引号。 如果你用的是正常的config的话

train_pipeline = [
    dict(type='LoadSingleRSImagFromFile')

要这么写,理论上不会出现这个错误。 你可以再检查一下你的

'RandomRotFlip', 'Albu', 'LoadSingleRSImageFromFile', 'ConcatCDInput',

这个位置,是否有 LoadSingleRSImagFromFile

十分感谢,是我拼写有问题

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants