[3D Image Segmentation] 3D Image Segmentation 2 based on Pytorch (Basic Data Flow)

BuildingpytorchThe data read by the training model has templates for reference and routines. I believe everyone who has used it knows this. I will also give a template of the routine to facilitate learning and inquiry.

At the same time, you can also refer to the previous article to study a relatively simple data construction method for 3D classification tasks. The link is here: [ 3D image classification] 3D stereoscopic image classification based on Pytorch 1 (Basics)

When it comes to the data construction for this training, it is a little more complicated than the blog referenced above. That is, after having the original picture and the mask picture, there is an additional center point coordinate and radius of the nodule target.

That means that after we read the three-dimensional information of the original image and mask image, we cannot directly put it into training, because the sizes are also different and there is too much background information. Then you need to cut out the target image of a fixed size area based on the coordinate information of the nodule target, and then put it in for training.

At this point, the entire process is basically clear.

  1. Get the original image, mask image, and the center point coordinates and radius of the nodule target
  2. Cropping operation, taking out input information of fixed size

In order to facilitate debugging and check whether the cropping is correct, use a check operation, which will be perfect.

1. Training data preprocessing

Luna16The original data is relatively complex and not intuitive enough. If this part of the data processing is done in the training stage, it will consume a lot of time and memory resources. Therefore, it is necessary to pre-process this relatively complex data into simpler, intuitive, one-to-one data relationships.

The 888 CT images in the LUNA16 data set are evenly divided into 10 subsets and stored in 10 folders subset0-subset9. The image storage method of this data set is MetaImage (mhd/raw) format. Each mhd Each file stores a separate corresponding raw file.

  • raw binary file, storing pixel data;
  • mhd file stores information

These two parts exist at the same time, indicating a complete message. For the above processing code about Luna16, you can refer to [Small target] vnet pulmonary nodule 3D image segmentation by the author Just handle this. For this, I will give a brief introduction to the processing steps:

  1. According to the nodule annotation information, obtain the coordinate information of the annotated nodule, and generate a mask 3-dimensional data block, the size of which is the same as the original CT image size; < /span>
  2. According to the lung area segmentation map and the original CT image processing, the information of removing the lung area and leaving only the lung parenchyma is obtained. For mask Treat it the same way;
  3. According to x、y、z the space information in three directions, perform resample operations to convert the original pixels represented by each dimension into Different scales, give resample to 1mm units;
  4. Finally, obtain the coordinate information of the nodule from after resample and save it to the file . maskcsv

At this point, under a relatively complicated process, their one-to-one correspondence has finally been sorted out smoothly. This blog post is basically a secondary reorganization of the author’s video part, as well as Weiwei’s work on improvements, testing, visualization, etc. After subsequent training, problems are discovered, and then problems are solved and optimized.

At this point, the files required for training have basically been sorted out. The path structure is as follows:

sk_output
├── bbox_annos
    ├── bbox_annos.csv

├── bbox_image
    ├── subset0
        ├── source_1.npy
        ├── source_2.npy
        └── ...
    ├── subset1
        ├── source_103.npy
        ├── source_104.npy
        └── ...
    ├── subset2
        ├── source_205.npy
        ├── source_206.npy
        └── ...
    ├── subset3
        ├── source_307.npy
        ├── source_308.npy
        └── ...
    └── ...


├── bbox_mask
    ├── subset0
        ├── source_1.npy
        ├── source_2.npy
        └── ...
    ├── subset1
        ├── source_103.npy
        ├── source_104.npy
        └── ...
    ├── subset2
        ├── source_205.npy
        ├── source_206.npy
        └── ...
    ├── subset3
        ├── source_307.npy
        ├── source_308.npy
        └── ...
    └── ...

in,

  1. bbox_annos.csv: Record the file name, coordinates and radius of the center point of the marked nodule;
  2. bbox_image: The image information of .npy, the element size is 0-255;
  3. bbox_mask: The information of .npy is equal to the number of corresponding files in , single Fileis consistent. There is only one target for the nodule, and the element value is . maskbbox_imagenpyshape0 or 1

2. Build the myDataset class

Building this data set actually involves just a few things:

  1. Read the original graph andmask graph;
  2. Get the center point coordinate information of the marked nodule, here it is obtained from the csv file;
  3. According to the coordinate information of the nodule center point, and then according to the size of patch to be cropped, determine the minimum and maximum coordinates of the three-dimensional hold;
  4. Crop out the area of ​​patch

At this point, the croppedpatch is the array containing the nodules, including the image array and the annotation arraymask, in one-to-one correspondence , used for training. Functions in class:

  1. getAnnotations function needs to obtain the file name and the corresponding coordinates of the nodule from the csv file, and finally store it as a dictionary;
  2. getNpyFile_Path Function, obtainimage and mask file paths;
  3. get_annos_labelFunction to obtain the nodule center point annotation information corresponding to the file.

The following is the entire code process:

import os
import torch
import torch.nn as nn
import torch.utils.data
from torch.utils.data import Dataset
import numpy as np
import cv2
from tqdm import tqdm
import random
import matplotlib.pyplot as plt

def getAnnotations(csv_file):
    content = pd.read_csv(csv_file, delimiter=',', header=None,
                              index_col=False)
    names = content[1].values
    coors = content[2].values

    dict_tp = {
   
    
    }
    for n, c in zip(names, coors):
        c_list = eval(c)
        if c_list:
            print(n, c_list, type(c_list))
            dict_tp[n] = c_list
    return dict_tp

class myDataset(Dataset):
    
    def __init__(self, csv_file, data_path, label_path, crop_size=(16, 96, 96)):
        """
        :param csv_file: 记录文件名和结节标记中心点坐标+半径的信息
        :param data_path: 存储原始CT图像
        :param label_path: 存储mask图像
        :param crop_size:   裁剪的尺寸
        """
        self.annosNameCenter_list = getAnnotations(csv_file)
        self.dataFile_paths = self.getNpyFile_Path(data_path)   # 图的path列表
        self.labelFile_paths = self.getNpyFile_Path(label_path)   # 标签的path列表

        self.annos_img_info =  = self.get_annos_label(self.dataFile_paths)  # 图的位置列表 输入进去  吐出  结节附近的图的【【图片位置,结节中心,半径】列表】

        self.crop_size = crop_size
        self.crop_size_z, self.crop_size_h, self.crop_size_w = crop_size

    def __getitem__(self, index):
        img_all = self.annos_img[index]     # 0 - image_path ; 1 - 结节的中心; 2 - 结节的半径
        label_all = self.annos_label[index]

        path, zyx_centerCoor, r = img_all

        img = np.load

Guess you like

Origin blog.csdn.net/wsLJQian/article/details/133966967
Recommended