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

关于用mmseg处理postsdam数据集的问题 #37

Open
1835969208 opened this issue Aug 8, 2024 · 5 comments
Open

关于用mmseg处理postsdam数据集的问题 #37

1835969208 opened this issue Aug 8, 2024 · 5 comments

Comments

@1835969208
Copy link

作者大人,我反复翻看往期issue,始终不太明白用mmseg处理postsdam数据集的目的以及作用。我已经按照readme完成了模型的预训练工作,需要用postsdam数据集对模型进行finetune。参照往期issue,我选用3_Ortho_IRRG.zip和5_Labels_all.zip。我去除了3_Ortho_IRRG.zip中所有的tfw文件,只保留了tif格式。同样,5_Labels_all.zip中也只保存了tif格式文件。然后整个文件夹的结构如下图所示。我不明白还需要用mmseg处理什么内容,是用mmseg进行训练吗?还是对图像进行裁剪(因为图像尺寸6000*6000太大的原因)?还有为什么不直接使用裁剪好的RGB图像呢。(小人实在是弄得有点迷糊了,希望博主能援助一下,完成整个项目后,我想录制一个从0复现整个项目的视频,希望对后面学习的同学有所帮助)。
image

@DotWang
Copy link
Collaborator

DotWang commented Aug 8, 2024

@1835969208 要裁剪和转换标签值,可能图像也要变成png方便读取,你不用mmseg来做数据处理也行,那就自己写脚本呗,这个数据集就没有裁剪好的啊,还得根据转换好的数据集标签类别顺序去修改相应的config,前提是你会改mmseg,不会改的话可能得学一下

@1835969208
Copy link
Author

感谢作者的帮助。我想自己写脚本进行数据的处理,跟您确定以下的几个要点。如果有什么不对的地方还请您能指出来。
1.我是要对3_Ortho_IRRG.zip和5_Labels_all.zip这两个文件夹下面的内容进行处理。
2.图像转换成png的格式
3.图像裁剪成多大呢?600*600可以吗?还是有特定的尺寸要求?
4.还有您说转换标签值,我的理解是改变5_Labels_all.zip下图像里面不同物体分割显示的颜色,对吗?那我根据什么去转换对应的标签值呢?或者说根据哪个文件呢?
5.您说的根据数据集标签类别顺序去修改相应的config,这个config是在哪个目录下的文件呀
以上是我的一些疑问,可能比较愚蠢。希望博主援助一下,万分感谢

@DotWang
Copy link
Collaborator

DotWang commented Aug 8, 2024

@1835969208 在其他项目中,我们手动转换好了potsdam的标签,然后修改mmseg的config,完成了训练,不过其他人可能希望用mmseg自带的脚本去转换potsdam的标签,而mmseg官方脚本转换后的标签格式和顺序和我们手动转换好的有差异,因此其他人可能不能直接用我们的config,他们需要对config进行修改,其他的issue就是告诉他们该如何修改的,例如:

ViTAE-Transformer/ViTAE-Transformer-Remote-Sensing#21
ViTAE-Transformer/ViTAE-Transformer-Remote-Sensing#9

不过对于SAMRS这个项目文中的实验来说,可以不配置mmseg的config,因为我已经给出微调代码了,你只需要准备好具有正确标签格式的数据集就好了,SAMRS这个项目和其他项目的共通点是,采用了具有相同标签格式和顺序的potsdam数据集,所以我让你去看其他项目的issue,理解标签顺序与改代码之间的关系

数据处理的原因是,除了图像太大以外,原始的标签是RGB三通道图像,要转成单通道,不然没法训练,至于你·是手动处理转标签,还是根据mmseg自带的转换工具去做,都可以,裁剪当然裁剪成一般大小的了,尺寸和步长看你需求,如果用mmseg训练的话,就涉及到config,这个说不清楚,你去学一下mmseg吧,我在之前的issue里都说过了,你不了解mmseg的运行原理我再说也没用

@1835969208
Copy link
Author

感谢作者大人的帮助。我现在是在尝试用mmseg自带的tools/convert_dataset/potsdam.py对potsdam数据集进行处理,然后用您的微调代码进行训练。目前运行微调代码始终显示标签值超出了模型预期的类别范围。我认为是我用mmseg自带的tools/convert_dataset/potsdam.py对potsdam数据集进行处理是标签的格式和顺序不对。反复翻看往期issue,仍然不太明白,希望作者大人再讲解一下正确的标签顺序和格式,万分感谢

@1835969208
Copy link
Author

十分感谢作者大人一直以来对我的帮助,同时祝博主七夕节快乐。我也很高兴在今天复现这个项目的所有功能。之前再potsdam数据集的处理上面遇到很多的疑惑,最后都得到了解决。下面是我对potsdam数据集预处理的脚本,希望能帮助后面更多进来学习的研0宝宝。最后,再次对作者这段时间的耐心援助表达感谢。

#################使用方法说明########
#大家用之前下载potsdam数据集,然后把3_Ortho_IRRG.zip和5_Labels_all.zip复制到一个新的文件夹下。运行下面的代码即可。
#运行命令示例:python convert_potsdam.py /data/potsdam --tmp_dir /tmp/potsdam --out_dir /data/output
#/path/to/dataset:这是包含原始数据的文件夹路径。
#--tmp_dir /path/to/tmp:可选参数,指定临时目录的路径。可以用于存放解压缩后的临时文件。如果不指定,系统会使用默认#的临时目录。
#--out_dir /path/to/output:可选参数,指定输出目录的路径。处理后的图像和标签将保存在这里。
###############################
`import argparse
import glob
import math
import os
import os.path as osp
import tempfile
import zipfile

import mmcv
import numpy as np
from mmengine.utils import ProgressBar, mkdir_or_exist

palette = {
0: (255, 255, 255), # Impervious surfaces (white)
1: (0, 0, 255), # Buildings (blue)
2: (0, 255, 255), # Low vegetation (cyan)
3: (0, 255, 0), # Trees (green)
4: (255, 255, 0), # Cars (yellow)
}

invert_palette = {v: k for k, v in palette.items()}

def convert_from_color(arr_3d, palette=invert_palette):
""" RGB-color encoding to grayscale labels """
arr_2d = np.zeros((arr_3d.shape[0], arr_3d.shape[1]), dtype=np.uint8)

for c, i in palette.items():
    m = np.all(arr_3d == np.array(c).reshape(1, 1, 3), axis=2)
    arr_2d[m] = i

return arr_2d

def parse_args():
parser = argparse.ArgumentParser(
description='Convert Potsdam dataset to mmsegmentation format')
parser.add_argument('dataset_path', help='Potsdam folder path')
parser.add_argument('--tmp_dir', help='path of the temporary directory')
parser.add_argument('-o', '--out_dir', help='output path')
parser.add_argument(
'--clip_size',
type=int,
help='clipped size of image after preparation',
default=512)
parser.add_argument(
'--stride_size',
type=int,
help='stride of clipping original images',
default=256)
args = parser.parse_args()
return args

def clip_big_image(image_path, clip_save_dir, args, to_label=False):
image = mmcv.imread(image_path)

h, w, c = image.shape
clip_size = args.clip_size
stride_size = args.stride_size

num_rows = math.ceil((h - clip_size) / stride_size) if math.ceil(
    (h - clip_size) /
    stride_size) * stride_size + clip_size >= h else math.ceil(
        (h - clip_size) / stride_size) + 1
num_cols = math.ceil((w - clip_size) / stride_size) if math.ceil(
    (w - clip_size) /
    stride_size) * stride_size + clip_size >= w else math.ceil(
        (w - clip_size) / stride_size) + 1

x, y = np.meshgrid(np.arange(num_cols + 1), np.arange(num_rows + 1))
xmin = x * clip_size
ymin = y * clip_size

xmin = xmin.ravel()
ymin = ymin.ravel()
xmin_offset = np.where(xmin + clip_size > w, w - xmin - clip_size,
                       np.zeros_like(xmin))
ymin_offset = np.where(ymin + clip_size > h, h - ymin - clip_size,
                       np.zeros_like(ymin))
boxes = np.stack([
    xmin + xmin_offset, ymin + ymin_offset,
    np.minimum(xmin + clip_size, w),
    np.minimum(ymin + clip_size, h)
],
                 axis=1)

if to_label:
    image = convert_from_color(image)

for box in boxes:
    start_x, start_y, end_x, end_y = box
    clipped_image = image[start_y:end_y,
                          start_x:end_x] if to_label else image[
                              start_y:end_y, start_x:end_x, :]
    idx_i, idx_j = osp.basename(image_path).split('_')[2:4]
    mmcv.imwrite(
        clipped_image.astype(np.uint8),
        osp.join(
            clip_save_dir,
            f'{idx_i}_{idx_j}_{start_x}_{start_y}_{end_x}_{end_y}.png'))

def main():
args = parse_args()
splits = {
'train': [
'2_10', '2_11', '2_12', '3_10', '3_11', '3_12', '4_10', '4_11',
'4_12', '5_10', '5_11', '5_12', '6_10', '6_11', '6_12', '6_7',
'6_8', '6_9', '7_10', '7_11', '7_12', '7_7', '7_8', '7_9'
],
'val': [
'5_15', '6_15', '6_13', '3_13', '4_14', '6_14', '5_14', '2_13',
'4_15', '2_14', '5_13', '4_13', '3_14', '7_13'
]
}

dataset_path = args.dataset_path
if args.out_dir is None:
    out_dir = osp.join('data', 'potsdam')
else:
    out_dir = args.out_dir

print('Making directories...')
mkdir_or_exist(osp.join(out_dir, 'img_dir', 'train'))
mkdir_or_exist(osp.join(out_dir, 'img_dir', 'val'))
mkdir_or_exist(osp.join(out_dir, 'ann_dir', 'train'))
mkdir_or_exist(osp.join(out_dir, 'ann_dir', 'val'))

zipp_list = glob.glob(os.path.join(dataset_path, '*.zip'))
print('Find the data', zipp_list)

for zipp in zipp_list:
    with tempfile.TemporaryDirectory(dir=args.tmp_dir) as tmp_dir:
        zip_file = zipfile.ZipFile(zipp)
        zip_file.extractall(tmp_dir)
        src_path_list = glob.glob(os.path.join(tmp_dir, '*.tif'))
        if not len(src_path_list):
            sub_tmp_dir = os.path.join(tmp_dir, os.listdir(tmp_dir)[0])
            src_path_list = glob.glob(os.path.join(sub_tmp_dir, '*.tif'))

        prog_bar = ProgressBar(len(src_path_list))
        for i, src_path in enumerate(src_path_list):
            idx_i, idx_j = osp.basename(src_path).split('_')[2:4]
            data_type = 'train' if f'{idx_i}_{idx_j}' in splits[
                'train'] else 'val'
            if 'label' in src_path:
                dst_dir = osp.join(out_dir, 'ann_dir', data_type)
                clip_big_image(src_path, dst_dir, args, to_label=True)
            else:
                dst_dir = osp.join(out_dir, 'img_dir', data_type)
                clip_big_image(src_path, dst_dir, args, to_label=False)
            prog_bar.update()

print('Removing the temporary files...')
print('Done!')

if name == 'main':
main()
`

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

2 participants