Pytorch DataLoader for custom dataset to load data image and mask correctly with a window size

huangapple go评论73阅读模式
英文:

Pytorch DataLoader for custom dataset to load data image and mask correctly with a window size

问题

我正在尝试为一个数据集编写自定义数据加载器,其中目录结构如下所示:

All_data
|
->Numpy_dat
| |
|  -> dat_0
|      -> dat_{0}_{0}.npy
|      .
|      .
| -> dat_1
|      -> dat_{0}_{0}.npy
|      -> dat_{0}_{1}.npy
|      .
|      .
|->mask_numpy
  |
  -> mask_0
     -> mask_{0}_{0}.npy
     -> mask_{0}_{1}.npy
     .
     .
  -> mask_1
     -> mask_{0}_{0}.npy
     -> mask_{0}_{1}.npy
     .
     .

打开此线程以了解如何使用重叠窗口下载这些补丁并跟踪主文件夹,即dat_{z}

子文件夹中的张量是来自同一图像的非重叠补丁。我根据一些存储在名为starts.npy的文件中的起始点提取它们。基本上,补丁是正方形的,但在行之间大小不同。假设原始图像的尺寸为254x254,我有一个起始编号的列表0、50、40、30... 因此,第一个补丁是行1和列1的50x50,但行1和列2是40x40,依此类推。

英文:

I am trying to write a custom data loader for a dataset where the directory structures is as follows:

All_data
|
->Numpy_dat
| |
|  -> dat_0
|      -> dat_{0}_{0}.npy
|      .
|      .
| -> dat_1
|      -> dat_{0}_{0}.npy
|      -> dat_{0}_{1}.npy
|      .
|      .
|->mask_numpy
  |
  -> mask_0
     -> mask_{0}_{0}.npy
     -> mask_{0}_{1}.npy
     .
     .
  -> mask_1
     -> mask_{0}_{0}.npy
     -> mask_{0}_{1}.npy
     .
     .

Opening this thread to understand how to download these patches with overlapping windows and keep track of the main folder i.e. dat_{z}.

The tensors in the sub-folder are non-overlapping patches coming from the same image. I simply extracted them based on some start points which are stored in a file called starts.npy. Essentially the patch is square but the size differs between rows. So suppose the original image is of the size 254x254 I have a list of start numbers 0, 50, 40, 30... so the first patch is a 50x50 for row 1 and column 1 but row 1 and column 2 is 40x40 and so on and so forth.

答案1

得分: 0

我理解你不需要代码部分的翻译。以下是代码外部的部分翻译:

"I don't fully grasp the tiling strategy you used so here is a simple example that may help you understand how to do it in your case.

Say that you tiled each image with patches of size (PW x PH) = 3x2 (width x height) and your image size is divisible by the patch size, say a 6x8 image. This means that an image is composed of NB_PW x NB_PH = 2x4 = 8 patches.

Then, you would store the 8 patches in your storage with names from dat_0_0.npy to dat_1_3.npy where the first number is the width index and the second one the height index."

接下来是代码部分,不需要翻译。

英文:

I don't fully grasp the tiling strategy you used so here is a simple example that may help you understand how to do it in your case.

Say that you tiled each image with patches of size (PW x PH) = 3x2 (width x height) and your image size is divisible by the patch size, say a 6x8 image. This means that an image is composed of NB_PW x NB_PH = 2x4 = 8 patches.

Then, you would store the 8 patches in your storage with names from dat_0_0.npy to dat_1_3.npy where the first number is the width index and the second one the height index.

You would first read all the patches in memory as such, in row-major order (this means that the width dimension index varies first):

import numpy as np
import torch

def read_patches(folder: str, nb_pw: int, nb_ph: int) -> list[torch.Tensor]:
    patches = []

    for pw_idx in range(nb_ph):
        for ph_idx in range(nb_pw):
            data = np.load(f"{folder}/dat_{pw_idx}_{ph_idx}.npy")
            patch = torch.from_numpy(data)
            patches.append(patch)

    return patches

Then, you can reassemble the patches into one image by creating an empty tensor of the appropriate size and pasting the patches into it:

import torch

PW = 3
PH = 2
NB_PW = 2
NB_PH = 4


def reassemble_patches(
    patches: list[torch.Tensor], pw: int, ph: int, nb_pw: int, nb_ph: int
) -> torch.Tensor:
    assert (
        len(patches) == nb_pw * nb_ph
    ), f"the number of provides patches ({len(patches)}) does not match the \
        expected number `nb_pw`x`nb_ph` of patches ({nb_pw * nb_ph})"

    output = torch.empty(size=(nb_ph * ph, nb_pw * pw))

    for pw_idx in range(nb_pw):
        pw_i_start = pw_idx * pw
        pw_i_end = (pw_idx + 1) * pw

        for ph_idx in range(nb_ph):
            ph_i_start = ph_idx * ph
            ph_i_end = (ph_idx + 1) * ph

            patch = patches[pw_idx + nb_pw * ph_idx]

            output[ph_i_start:ph_i_end, pw_i_start:pw_i_end] = patch

    return output

Finally, the main program:

def main():
    patches = read_patches("patches/folder/", NB_PW, NB_PH)
    full = reassemble_patches(patches, PW, PH, NB_PW, NB_PH)
    print(full)


if __name__ == "__main__":
    main()

huangapple
  • 本文由 发表于 2023年3月4日 02:50:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/75630836.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定