英文:
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()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论