def preprocessing_loc(self, pid): ''' stage A过程的预处理 :param pid: :return: ''' image_volume = self.__image_volume_data self.__org_volume_shape = self.__image_volume_data.shape # 1-重采样,默认层厚3mm first_dataset_item = self.__list_dataset_image[0] image_volume = image_resample(first_dataset_item, image_volume, g_slice_thickness) self.__resampled_shape = image_volume.shape # 2-设置window image_volume = set_ww_wl(image_volume, self.__roi_name, self.__modality, pid, self.__sol_format) save_images(image_volume, pid, '666', os.path.join(g_tmp_dir_base, self.__roi_name)) # 3-如果image数据长和宽不相等则调整为相等,否则不做处理 shape = image_volume.shape image_volume = processor.image_padding(image_volume, shape[1], shape[2]) self.__padded_shape = image_volume.shape # save_images(image_volume, pid, '02.image', os.path.join(g_tmp_dir_base, self.__roi_name)) # 4-根据超参数缩放图像 result_image_volume_data = processor.image_resize_3d( image_volume, self.__height, self.__width) # save_images(image_volume, pid, '03.image', os.path.join(g_tmp_dir_base, self.__roi_name)) return result_image_volume_data
def preprocessing(self, image_volume_data, pid): # 获取第一个slice的dicom信息,例如:spacing、orgin、thickness等参数,后面重采样使用 first_dataset_item = self.__dict_all_case_info[pid].first_dataset_item # 1-图像重采样,层厚设置为默认3mm image_volume_data_resampled = image_resample(first_dataset_item, image_volume_data, g_slice_thickness) # 2-设置窗宽窗位 image_volume_data_wwwl = set_ww_wl(image_volume_data_resampled, self.__roi_name, self.__modality, pid, self.__format) # 3-如果输入图像宽和高不相等,则变换为相等,如:512x512 --> 512x512; 192x256 --> 256x256; 1024x512 --> 1024x1024 image_volume_data_padded = processor.image_padding( image_volume_data_wwwl, image_volume_data_wwwl.shape[1], image_volume_data_wwwl.shape[2]) # save_images(image_volume_data_padded, pid, '02.image') # 4-缩放图像至指定的大小,大小为超参数,人为指定,例如: # 'Spinal_Cord': Parameter(... depth=64, height=96, width=96 image_volume_data_resized = processor.image_resize_3d( image_volume_data_padded, self.__height, self.__width) result_image_volume_data = image_volume_data_resized return result_image_volume_data
def preprocessing_seg(self, label_volume_data_loc): image_volume_data = self.__image_volume_data first_dataset_item = self.__list_dataset_image[0] pid = os.path.basename(self.__one_case_path) ## 1-label_loc定位图像处理 # 1-对label_loc定位图像重采样 label_volume_data_loc_resampled = image_resample( first_dataset_item, label_volume_data_loc, g_slice_thickness) # 2-对于label_loc定位图像,如果宽高不相等,则调整为相等 label_volume_data_loc_shape_fixed = processor.image_padding( label_volume_data_loc_resampled, label_volume_data_loc_resampled.shape[1], label_volume_data_loc_resampled.shape[2]) ## 2-根据label_loc定位图像对image数据处理 # 2.1-重采样,默认层厚3mm image_volume_data_resampled = image_resample(first_dataset_item, image_volume_data, g_slice_thickness) self.__resampled_shape = image_volume_data_resampled.shape # 2.2-设置window image_volume_data_wwwl = set_ww_wl(image_volume_data_resampled, self.__roi_name, self.__modality, pid, self.__sos_format) # 2.3-如果image数据长和宽不相等则调整为相等,否则不作处理 image_volume_data_shape_fixed = processor.image_padding( image_volume_data_wwwl, image_volume_data_wwwl.shape[1], image_volume_data_wwwl.shape[2]) self.__padded_shape = image_volume_data_shape_fixed.shape # 2.4-根据label_loc定位图像对image数据进行抠图 if self.__roi_name == 'Len_L' or self.__roi_name == 'Len_R' or self.__roi_name == 'Optic_Nerve_L' or self.__roi_name == 'Optic_Nerve_R': box = processor.get_bounding_box(label_volume_data_loc_shape_fixed, self.__predifined_box_size[0], xy_padding=g_xy_padding, z_padding=4) else: box = processor.get_bounding_box(label_volume_data_loc_shape_fixed, self.__predifined_box_size[0]) self.__crop_box = box image_volume_data_box = np.zeros( [self.__predifined_box_size[0], box[3] - box[2], box[5] - box[4]], np.uint8) image_volume_data_box[0:box[1] - box[0]] = image_volume_data_shape_fixed[ box[0]:box[1], box[2]:box[3], box[4]:box[5]] # save_images(image_volume_data_box, pid, '03.image', os.path.join(g_tmp_dir_base, self.__roi_name)) # 2.5-根据超参(如bbox=[96, 128, 128])进行缩放 image_volume_data_resized = processor.image_resize_3d( image_volume_data_box, self.__predifined_box_size[1], self.__predifined_box_size[2]) save_images(image_volume_data_resized, pid, '795', os.path.join(g_tmp_dir_base, self.__roi_name)) return image_volume_data_resized
def postprocessing(self, pid, real_slices, list_predictions): ''' 图像后处理操作。由于训练的时候采用的是将一个病人的volume数据patch成多个depth x height x width的数据进行训练的, 因此预测的时候也是生成多个patch,然后将每个patch合并还原为一个volume :param pid: :param real_slices: :param list_predictions: :return: ''' # 将多个patch合并 batches = len(list_predictions) label_volume = np.zeros( (batches * self.__depth, self.__height, self.__width, 1), np.float) for i in range(len(list_predictions)): label_volume[i * self.__depth:i * self.__depth + self.__depth] = list_predictions[i] # 修改数据预测结果数据形状,主要是去掉了channel维度:[depth, height, width, 1] --> [depth, height, width] label_volume_data_location = np.reshape( label_volume, (batches * self.__depth, self.__height, self.__width)) # 由于Dataset4TrainLocation::preprocessing中最后一步将label数据进行了normalization操作,即将0~255归一化到0~1区间了, # 所以这里要乘以255还原回去,并且将数据类型有float修改为uint8 label_volume_data_location = np.clip(label_volume_data_location * 255, 0, 255).astype(np.uint8) # save_images(label_volume_data_location, pid, '02.label') # 预处理的流程先后顺序为:resample;image_padding;image_resize, # 所以这里的流程应该和预处理正好相反:image_resize;image_padding;resample # 预处理:A --> B --> C # 后处理:iC-->iB-->iA # 1- 反向image_resize org_height = self.__dict_all_case_info[pid].shape[1] org_width = self.__dict_all_case_info[pid].shape[2] length = max(org_height, org_width) label_volume_resized = processor.image_resize_3d( label_volume_data_location, length, length) # 2-反向image_padding image_ipadding = label_volume_resized[:, :, (org_height - org_width) // 2:(length - (org_height - org_width) // 2)] # 3-反向重采样 # 对预测生成的label进行反重采样,预处理里面将所有层厚都采样成了3mm后,这个地方要变换回原始的层厚 # 例如:输入数据层厚为1mm,预处理后就变成了3mm,然后进行预测,预测完了之后的图像是3mm,然后再变换回原来的1mm org_thickness = self.__dict_all_case_info[ pid].first_dataset_item.SliceThickness self.__dict_all_case_info[ pid].first_dataset_item.SliceThickness = g_slice_thickness label_volume_data_resampled = image_resample( self.__dict_all_case_info[pid].first_dataset_item, image_ipadding[0:real_slices], org_thickness) return label_volume_data_resampled
def preprocessing(self, image_volume_data, label_volume_data): ''' 对一个病例的image和label进行数据预处理 :param image_volume_data: :param label_volume_data: :param pid: :return: ''' # 1-如果输入图像宽和高不相等,则变换为相等,如:512x512 --> 512x512; 192x256 --> 256x256; 1024x512 --> 1024x1024 shape = image_volume_data.shape image_volume = processor.image_padding(image_volume_data, shape[1], shape[2]) # 2-缩放图像至指定的大小,大小为超参数,人为指定,例如: # 'Spinal_Cord': Parameter(... depth=64, height=96, width=96 image_volume = processor.image_resize_3d(image_volume, self.__height, self.__width) # 3-如果输入label图像宽和高不相等,则变换为相等,如:512x512 --> 512x512; 192x256 --> 256x256; 1024x512 --> 1024x1024 shape = label_volume_data.shape label_volume = processor.image_padding(label_volume_data, shape[1], shape[2]) # 4-缩放label图像至指定的大小,大小为超参数,人为指定,例如: # 'Spinal_Cord': Parameter(... depth=64, height=96, width=96 label_volume = processor.image_resize_3d(label_volume, self.__height, self.__width) # 5-对label图像进行二值化阈值处理,小于127设为0,大于127设为255 label_volume = processor.image_threshold_binaray_3d(label_volume, 127) # save_images(label_volume_data_dilated, pid, '03.label') # 6-将label图像规范化处理:[0 ~ 255] --> [0 ~ 1] label_volume = processor.normalize_image_data(label_volume) return image_volume, label_volume
def postprocessing_loc(self, pid, real_slices, list_predictions): ''' stage A过程,当预测出location图像后的后处理,部分过程参考Dataset4PredictLocation中的后处理过程 :param pid: :param real_slices: :param list_predictions: :return: ''' batches = len(list_predictions) label_volume = np.zeros( (batches * self.__depth, self.__height, self.__width, 1), np.float) for i in range(len(list_predictions)): label_volume[i * self.__depth:i * self.__depth + self.__depth] = list_predictions[i] label_volume = np.reshape( label_volume, (batches * self.__depth, self.__height, self.__width)) label_volume = np.clip(label_volume * 255, 0, 255).astype(np.uint8) label_volume = label_volume[0:real_slices] # save_images(label_volume, '00', '1', os.path.join(g_tmp_dir_base, self.__roi_name)) ''' preprocessing_loc中的预处理过程为:resample;image_padding;image_resize 因此,这里的后处理过程为:image_resize;image_padding;resample ''' # 1-反向image_resize shape = self.__padded_shape label_volume = processor.image_resize_3d(label_volume, shape[1], shape[2]) # save_images(label_volume, '00', '2', os.path.join(g_tmp_dir_base, self.__roi_name)) # 2-反向image_padding shape = self.__resampled_shape label_volume = processor.image_ipadding(label_volume, shape[1], shape[2]) # save_images(label_volume, '00', '3', os.path.join(g_tmp_dir_base, self.__roi_name)) # 3-反向重采样 first_dataset_item = self.__list_dataset_image[0] org_thickness = first_dataset_item.SliceThickness first_dataset_item.SliceThickness = g_slice_thickness label_volume = image_resample(first_dataset_item, label_volume, org_thickness) first_dataset_item.SliceThickness = org_thickness save_images(label_volume, pid, '753', os.path.join(g_tmp_dir_base, self.__roi_name)) return label_volume
def postprocessing_seg(self, pid, list_predictions): label_volume_data_box = list_predictions[0][0] label_volume_data_box_reshaped = np.reshape( label_volume_data_box, (label_volume_data_box.shape[0], label_volume_data_box.shape[1], label_volume_data_box.shape[2])) label_volume_data_box_reshaped = np.clip( label_volume_data_box_reshaped * 255, 0, 255).astype(np.uint8) ''' preprocessing_seg预处理流程为:image_resample;image_padding;crop; image_resize 因此,这里后处理的流程为:image_resize;crop; image_padding;image_resample ''' # 1-反向resize box = self.__crop_box label_volume_data_box_resized = processor.image_resize_3d( label_volume_data_box_reshaped, box[3] - box[2], box[5] - box[4]) # 2-反向crop shape = self.__padded_shape label_volume_data_icroped = np.zeros(shape, dtype=np.uint8) label_volume_data_icroped[ box[0]:box[1], box[2]:box[3], box[4]:box[5]] = label_volume_data_box_resized[0:box[1] - box[0]] # 3-反向pimage_padding shape = self.__resampled_shape label_volume_data_ipadded = processor.image_ipadding( label_volume_data_icroped, shape[1], shape[2]) # 4-反向重采样 label_volume_data = np.zeros(self.__image_volume_data.shape, np.uint8) first_dataset_item = self.__list_dataset_image[0] org_thickness = first_dataset_item.SliceThickness # first_dataset_item.SliceThickness = 1.0 first_dataset_item.SliceThickness = g_slice_thickness label_volume_data_resampled = image_resample( first_dataset_item, label_volume_data_ipadded, org_thickness) first_dataset_item.SliceThickness = org_thickness # label_volume_data_shape_fixed = processor.image_padding( # label_volume_data_resampled1, label_volume_data_resampled1.shape[1], label_volume_data_resampled1.shape[2]) # # end_z = min(label_volume_data_shape_fixed.shape[0] - 1, box[0] + label_volume_data_box_resized.shape[0]) # label_volume_data_shape_fixed[box[0]:end_z, box[2]:box[3], box[4]:box[5]] = label_volume_data_box_resized[0:end_z - box[0]] # # first_dataset_item.SliceThickness = g_slice_thickness # label_volume_data_resampled2 = image_resample(first_dataset_item, label_volume_data_shape_fixed, org_thickness) # first_dataset_item.SliceThickness = org_thickness # # org_height = first_dataset_item.Rows # org_width = first_dataset_item.Columns # length = max(org_height, org_width) # result = label_volume_data_resampled2[:, :, (org_height - org_width) // 2:(length - (org_height - org_width) // 2)] if self.__roi_name == 'Len_L' or self.__roi_name == 'Len_R' or self.__roi_name == 'Optic_Nerve_L' or self.__roi_name == 'Optic_Nerve_R': # result = processor.image_dilate(label_volume_data_resampled, 1) result = label_volume_data_resampled else: result = processor.image_erode(label_volume_data_resampled, 1) result = processor.image_keep_max_region(result) result = processor.image_dilate(result, 1) return result
def preprocessing(self, pid, image_volume_data, label_volume_data, label_volume_data_loc): first_dataset_item = self.__dict_all_case_info[pid].first_dataset_item ## 1-label_loc # 1.1-对lable_loc定位图像进行重采样,默认层厚3mm label_volume_data_loc_resampled = image_resample( first_dataset_item, label_volume_data_loc, g_slice_thickness) # 1.2-对lable_loc定位图像进行宽和高调整为相等 label_volume_data_loc_shape_fixed = processor.image_padding( label_volume_data_loc_resampled, label_volume_data_loc_resampled.shape[1], label_volume_data_loc_resampled.shape[2]) # 1.3-根据label_loc定位图像获取boundingbox if self.__roi_name == 'Len_L' or self.__roi_name == 'Len_R' or \ self.__roi_name == 'Optic_Nerve_L' or self.__roi_name == 'Optic_Nerve_R' or self.__roi_name == 'Pituitary': box = processor.get_bounding_box(label_volume_data_loc_shape_fixed, self.__depth, xy_padding=g_xy_padding, z_padding=4) else: box = processor.get_bounding_box(label_volume_data_loc_shape_fixed, self.__depth) self.__dict_all_case_info[pid].box = box ## 2-image # 2.1-对image数据进行重采样,默认层厚为3mm image_volume_data_resampled = image_resample(first_dataset_item, image_volume_data, g_slice_thickness) # 对重采样之后的image数据设置window image_volume_data_wwwl = set_ww_wl(image_volume_data_resampled, self.__roi_name, self.__modality, pid, self.__sos_format) # save_images(image_volume_data_wwwl, pid, '02image') # 2.2-对image数据进行宽和高调整为相等 image_volume_data_shape_fixed = processor.image_padding( image_volume_data_wwwl, image_volume_data_wwwl.shape[1], image_volume_data_wwwl.shape[2]) # 2.3-根据boudingbox抠图,注意:get_bounding_box返回的图像宽和高总是相等的 image_volume_data_box = np.zeros( [self.__depth, box[3] - box[2], box[5] - box[4]], np.uint8) image_volume_data_box[0:box[1] - box[0]] = image_volume_data_shape_fixed[ box[0]:box[1], box[2]:box[3], box[4]:box[5]] # save_images(image_volume_data_box, pid, '03image') # 2.4-由于get_bounding_box返回的图像宽和高总是相等的,所以将抠图之后的image bbox data直接进行缩放 image_volume_data_resized = processor.image_resize_3d( image_volume_data_box, self.__height, self.__width) save_images(image_volume_data_resized, pid, 'image', os.path.join(g_tmp_dir_base, self.__roi_name)) result_image_volume_data = image_volume_data_resized # 为了观察理解,可以将预处理之后的图像保存 # save_images(result_image_volume_data, pid, 'image_bbox') ## 3-label # 3.1-对label数据进行重采样 label_volume_data_resampled = image_resample(first_dataset_item, label_volume_data, g_slice_thickness) # save_images(label_volume_data_resampled, pid, '02label') # 3.2-对label数据进行宽和高调整为相等 label_volume_data_shape_fixed = processor.image_padding( label_volume_data_resampled, label_volume_data_resampled.shape[1], label_volume_data_resampled.shape[2]) # 3.3-根据boudingbox抠图,注意:get_bounding_box返回的图像宽和高总是相等的 label_volume_data_box = np.zeros( [self.__depth, box[3] - box[2], box[5] - box[4]], np.uint8) label_volume_data_box[0:box[1] - box[0]] = label_volume_data_shape_fixed[ box[0]:box[1], box[2]:box[3], box[4]:box[5]] # 3.4-由于get_bounding_box返回的图像宽和高总是相等的,所以将抠图之后的image bbox data直接进行缩放 label_volume_data_resized = processor.image_resize_3d( label_volume_data_box, self.__height, self.__width) save_images(label_volume_data_resized, pid, 'label', os.path.join(g_tmp_dir_base, self.__roi_name)) # 为了观察理解,可以将预处理之后的图像保存 # save_images(label_volume_data_resized, pid, 'label_bbox') # 对label数据归一化到0~1区间 result_label_volume_data = processor.normalize_image_data( label_volume_data_resized) return result_image_volume_data, result_label_volume_data