def get_data_array(data_dir, new_shape, shuffle=False,unlabeled=False): path_array = glob.glob(f"{data_dir}/*") if shuffle: np.random.shuffle(path_array) nr_imgs = len(path_array) old_shape = (86,333,271) factor = (new_shape[0]/old_shape[0],new_shape[1]/old_shape[1],new_shape[2]/old_shape[2]) img_dim = (nr_imgs,round(factor[0]*old_shape[0]),round(factor[1]*old_shape[1]), round(factor[2]*old_shape[2])) data_array = np.zeros(img_dim) label_array = np.zeros(img_dim) for i, path in enumerate(path_array): mr_img = GetArrayFromImage(ReadImage(f"{path}/mr_bffe.mhd")) data_array[i] = zoom(mr_img,zoom=factor,order=1) if unlabeled==False: seg = GetArrayFromImage(ReadImage(f"{path}/prostaat.mhd")) label_array[i] = zoom(seg,zoom=factor,order=1) data_array = np.expand_dims(data_array,1) if unlabeled==False: label_array = np.expand_dims(label_array,1) return data_array, label_array else: return data_array
def get_pretrain_data(data_dir, new_shape): nr_imgs = 50 #old_shape = (86,333,271) # img_dim = (nr_imgs,round(factor[0]*old_shape[0]),round(factor[1]*old_shape[1]), # round(factor[2]*old_shape[2])) img_dim = (nr_imgs,new_shape[0],new_shape[1],new_shape[2]) data_array = np.zeros(img_dim) label_array = np.zeros(img_dim) for i in range(nr_imgs): subj_str = f"{data_dir}/Case{i:02d}" mr_img = GetArrayFromImage(ReadImage(subj_str+".mhd")) old_shape = mr_img.shape factor = (new_shape[0]/old_shape[0],new_shape[1]/old_shape[1],new_shape[2]/old_shape[2]) data_array[i] = zoom(mr_img,zoom=factor,order=1) seg = GetArrayFromImage(ReadImage(subj_str+"_segmentation.mhd")) label_array[i] = zoom(seg,zoom=factor,order=1) data_array = np.expand_dims(data_array,1) label_array = np.expand_dims(label_array,1) return data_array, label_array
def get_data_array(data_dir, shuffle=False): path_array = glob.glob(f"{data_dir}/*") if shuffle: np.random.shuffle(path_array) nr_imgs = len(path_array) data_array = np.zeros((nr_imgs, 86, 333, 271)) label_array = np.zeros((nr_imgs, 86, 333, 271)) for i, path in enumerate(path_array): data_array[i] = GetArrayFromImage(ReadImage(f"{path}/mr_bffe.mhd")) label_array[i] = GetArrayFromImage(ReadImage(f"{path}/prostaat.mhd")) return data_array, label_array
def get_pretraining_data(input_pretraining_dir, input_sample_shape=(16, 80, 64)): nr_imgs = 50 full_shape = tuple([nr_imgs] + list(input_sample_shape)) resized_mr_imgs = np.zeros(full_shape) resized_seg_imgs = np.zeros(full_shape) for i in range(nr_imgs): full_mr_img = GetArrayFromImage(ReadImage(f"{input_pretraining_dir}/Case{i:02}.mhd")) full_seg_img = GetArrayFromImage(ReadImage(f"{input_pretraining_dir}/Case{i:02}_segmentation.mhd")) full_img_shape = full_mr_img.shape zoom_factor = (input_sample_shape[0] / full_img_shape[0], input_sample_shape[1] / full_img_shape[1], input_sample_shape[2] / full_img_shape[2]) resized_mr_imgs[i] = zoom(full_mr_img, zoom_factor, order=1) resized_seg_imgs[i] = zoom(full_seg_img, zoom_factor, order=1) return resized_mr_imgs, resized_seg_imgs
def read_dicom(path, label=False): name = ImageSeriesReader_GetGDCMSeriesFileNames(path) img = ReadImage(name) if label: arr = GetArrayFromImage(img) arr = arr > 2000 else: img = sitk.Cast(img, sitk.sitkFloat32) img = sitk.IntensityWindowing(img, -1024, 1024, 0.0, 1.0) # WriteImage(img, 'test.vtk') arr = GetArrayFromImage(img) arr = arr[..., np.newaxis] print(arr.shape) return arr
def get_transformed_image(input_fixed_img, input_moving_img, img_type="pros", iteration=max_iteration): temp_dir = f"{IMAGES_PATH}/{input_fixed_img}-{input_moving_img}" image_path = f"{temp_dir}/{iteration}/{img_type}/result.mhd" return GetArrayFromImage(ReadImage(image_path))
def get_images(input_img_paths, input_transform): print("results", end=" ", flush=True) fixed_mr_img = GetArrayFromImage(ReadImage(input_img_paths[0])) moving_mr_img = GetArrayFromImage(ReadImage(input_img_paths[1])) fixed_pros_img = GetArrayFromImage(ReadImage(input_img_paths[2])) moving_pros_img = GetArrayFromImage(ReadImage(input_img_paths[3])) transformed_moving_mr_img = transform_img(input_img_paths[1], input_transform) transformed_moving_pros_img = transform_img(input_img_paths[3], input_transform) jacobian_determinant_img = get_determinant_img(input_transform) return np.array([ fixed_mr_img, fixed_pros_img, moving_mr_img, moving_pros_img, transformed_moving_mr_img, transformed_moving_pros_img, jacobian_determinant_img, (jacobian_determinant_img < 0) * 255 ])
def _binshrink(img_dir, scale_factor, outpath): """ Shrink the image by an integer factor. Confirmed only on even-dimension images currently. May need to add padding. This is working! Produces almost exactly sane output as CV2 method but seems to round 0.5 values down to 0 :param scale_factor: :return: """ print('scaling by int') img_path_list = get_img_paths(img_dir) last_img_index = 0 z_chuncks = [] scale_factor = int(1/ scale_factor) for i in range(scale_factor, len(img_path_list) + scale_factor, scale_factor): slice_paths = [x for x in img_path_list[last_img_index: i + 1]] slice_imgs = ReadImage(slice_paths) z_chuncks.append(BinShrink(slice_imgs, [scale_factor, scale_factor, scale_factor])) last_img_index = i first_chunk = True for j in z_chuncks: array = GetArrayFromImage(j) if first_chunk: assembled = array first_chunk = False else: assembled = np.vstack((assembled, array)) #Write the image imgout = GetImageFromArray(assembled) WriteImage(imgout, outpath)
def read_nrrd(file_name): ''' 读取nrrd体数据文件 :param file_name:nrrd文件路径 :return:nd-array,(z,y,x) ''' img = ReadImage(file_name) return GetArrayFromImage(img)
def read_VTK(file_name): ''' 读取VTK体数据文件 :param file_name:VTK文件路径 :return:nd-array,(z,y,x) ''' img = ReadImage(file_name) return GetArrayFromImage(img)
def __call__(self, image): outputs = None image_arr = GetArrayFromImage(image) pelvis, diaphram = self._SmartCrop__get_coordinates(image_arr, -70, 25) if (pelvis >= 0) and (diaphram <= image_arr.shape[0]) and (pelvis < diaphram): outputs = Crop(image, [0, 0, int(pelvis)], [0, 0, int(image_arr.shape[0] - diaphram)]) return outputs
def test_itk_loader(): fname = (Path(__file__).parent / 'resources' / 'itk' / '1.0.000.000000.0.00.0.0000000000.0000.0000000000.000.mhd') o = SimpleITKLoader.load(fname=fname) assert o['path'] == fname assert GetArrayFromImage(o['img']).shape == (476, 512, 512) with pytest.raises(FileLoaderError): SimpleITKLoader.load(fname=fname.with_name(f'{fname.stem}.zraw'))
def auto_bounding_box(self, filelist): self.callback("Determining crop bounding box") z_proj_path = os.path.join(self.configOb.meta_path, "max_intensity_z.png") # Start with a z-projection zp = zproject.Zproject(filelist, z_proj_path, force=True) zp.update.connect(self.update_slot) zp.run_onthisthread() zp_im = ReadImage(z_proj_path) reader = Imreader(filelist) try: testimg = reader.imread(filelist[0]) except IOError as e: raise HarpDataError('Failed to read {}. Is it corrupt'.format( filelist[0])) datatype = testimg.dtype if datatype is np.uint16: outval = 65535 else: outval = 255 # Apply otsu threshold and remove all but largest component seg = OtsuThreshold(zp_im, 0, outval, 128) seg = ConnectedComponent(seg) # label non-background pixels seg = RelabelComponent( seg) # relabel components in order of ascending size # seg = seg == 1 # discard all but largest component # Get bounding box label_stats = LabelStatisticsImageFilter() label_stats.Execute(zp_im, seg) bbox = list( label_stats.GetBoundingBox(1)) # xmin, xmax, ymin, ymax (I think) # Padding self.imdims = testimg.shape padding = int(np.mean(self.imdims) * 0.04) bbox = self.pad_bounding_box(bbox, padding) # Callback! self.callback(tuple(bbox)) # Crop the z-projection and write to metadata zp_arr = GetArrayFromImage(zp_im) zp_crop = GetImageFromArray(zp_arr[bbox[2]:bbox[3], bbox[0]:bbox[1]]) WriteImage(zp_crop, os.path.join(self.configOb.meta_path, "crop_result.png")) return bbox
def show_slices(input_fixed_img_name, input_moving_img_name, input_slice_nr=40, save=True): if save: temp_path = f"{RESULTS_PATH}/slices/{input_fixed_img_name}-{input_moving_img_name}" if not os.path.exists(temp_path): os.mkdir(temp_path) temp_path = f"{temp_path}/{input_slice_nr}" if not os.path.exists(temp_path): os.mkdir(temp_path) bits = 11 fixed_mr_img_slice = GetArrayFromImage( ReadImage(f"{DATA_PATH}/{input_fixed_img_name}/mr_bffe.mhd"))[ input_slice_nr, :, :] / 2**bits * 255 fixed_pros_img_slice = GetArrayFromImage( ReadImage(f"{DATA_PATH}/{input_fixed_img_name}/prostaat.mhd"))[ input_slice_nr, :, :] * 255 moving_mr_img_slice = GetArrayFromImage( ReadImage(f"{DATA_PATH}/{input_moving_img_name}/mr_bffe.mhd"))[ input_slice_nr, :, :] / 2**bits * 255 moving_pros_img_slice = GetArrayFromImage( ReadImage(f"{DATA_PATH}/{input_moving_img_name}/prostaat.mhd"))[ input_slice_nr, :, :] * 255 # transformed_moving_mr_img_slice = GetArrayFromImage(ReadImage(f"{IMAGES_PATH}/{fixed_img_name}-{moving_img_name}/2/mr/result.mhd"))[input_slice_nr, :, :] / 2 ** bits * 255 # transformed_moving_pros_img_slice = GetArrayFromImage(ReadImage(f"{IMAGES_PATH}/{fixed_img_name}-{moving_img_name}/2/pros/result.mhd"))[input_slice_nr, :, :] * 255 for i, img_slice in enumerate( [ fixed_mr_img_slice, fixed_pros_img_slice, moving_mr_img_slice, moving_pros_img_slice ] ): #, transformed_moving_mr_img_slice, transformed_moving_pros_img_slice]): if save: show_image_save( img_slice, f"{temp_path}/{names[i]}_{input_fixed_img_name}_{input_moving_img_name}_{input_slice_nr}.png" ) else: show_image_save(img_slice)
def get_data_array(data_dir, new_shape): path_array = glob.glob(f"{data_dir}/*") nr_imgs = len(path_array) old_shape = (86,333,271) factor = (new_shape[0]/old_shape[0],new_shape[1]/old_shape[1],new_shape[2]/old_shape[2]) img_dim = (nr_imgs,round(factor[0]*old_shape[0]),round(factor[1]*old_shape[1]), round(factor[2]*old_shape[2])) data_array = np.zeros(img_dim) if ranking==False: label_array = np.zeros((nr_imgs,old_shape[0],old_shape[1],old_shape[2])) for i, path in enumerate(path_array): mr_img = GetArrayFromImage(ReadImage(f"{path}/mr_bffe.mhd")) data_array[i] = zoom(mr_img,zoom=factor,order=1) if ranking==False: label_array[i] = GetArrayFromImage(ReadImage(f"{path}/prostaat.mhd")) data_array = np.expand_dims(data_array,1) if ranking==False: return data_array, label_array elif ranking==True: return data_array
def test_itk_loader(): fname = (Path(__file__).parent / "resources" / "itk" / "1.0.000.000000.0.00.0.0000000000.0000.0000000000.000.mhd") loader = SimpleITKLoader() o = loader.load(fname=fname)[0] img = loader.load_image(fname) assert o["path"] == fname assert o["hash"] == loader.hash_image(img) assert GetArrayFromImage(img).shape == (476, 512, 512) with pytest.raises(FileLoaderError): SimpleITKLoader().load(fname=fname.with_name(f"{fname.stem}.zraw"))
def get_results(input_img_paths, input_transform): print("results", end=" ", flush=True) fixed_mr_img = GetArrayFromImage(ReadImage(input_img_paths[0])) moving_mr_img = GetArrayFromImage(ReadImage(input_img_paths[1])) transformed_moving_mr_img = transform_img(input_img_paths[1], input_transform) fixed_pros_img = GetArrayFromImage(ReadImage(input_img_paths[2])) moving_pros_img = GetArrayFromImage(ReadImage(input_img_paths[3])) transformed_moving_pros_img = transform_img(input_img_paths[3], input_transform) before_dice = dice(fixed_pros_img, moving_pros_img) after_dice = dice(fixed_pros_img, transformed_moving_pros_img) score_string = f"{fixed_img_name}\t{moving_img_name}\t{before_dice}\t" for func in [nmi, ncc, msd]: score_string += str(func(fixed_mr_img, moving_mr_img)) + "\t" score_string += f"\t{after_dice}\t" for func in [nmi, ncc, msd]: score_string += str(func(fixed_mr_img, transformed_moving_mr_img)) + "\t" score_string += "\t" + str(time.time() - total_begin_time) print(score_string, end=" ", flush=True) return score_string
def readdcmseries(folderpath, get_seriesinfo=True): """ This function used to read information from dicom series folder. Input: folderpath: path to dicom series folder. Returns: dicom_names, spacing, machine, image_array, shape, errorseries. Note.: SimpleITK read image in the order of z-y-x, namely the number of slice-width-height; However,SimpleITK read origin and spacing in the order of x-y-z """ reader = ImageSeriesReader() dicom_names = reader.GetGDCMSeriesFileNames(folderpath) # series info if get_seriesinfo: reader.SetFileNames(dicom_names) reader.MetaDataDictionaryArrayUpdateOn() reader.LoadPrivateTagsOn() series_ids = reader.GetGDCMSeriesIDs(folderpath) # get all series id series_file_names = reader.GetGDCMSeriesFileNames( folderpath, series_ids[0]) # get the first series reader.SetFileNames(series_file_names) # extract info slice_number = 0 # select the first slice try: image = reader.Execute() # type: sitk.Image image_array = GetArrayFromImage(image) # z, y, x shape = image.GetSize() spacing = image.GetSpacing() # x, y, z errorseries = '' except RuntimeError: image_array = 0 # z, y, x shape = 0 spacing = (0, 0, 0) errorseries = folderpath print(f'{folderpath} dimension error!\n') machine = reader.GetMetaData(slice_number, '0008|0070') manufacturer_model_name = reader.GetMetaData(slice_number, '0008|1090') # keys = reader.GetMetaDataKeys(slice_number) # get all tags key, then we also can get all information # info = [] # for k in keys: # print(f'{k} {reader.GetMetaData(0, k)}') else: # one dcm info spacing, machine, image_array, shape = readdcmfile(dicom_names[0]) return dicom_names, spacing, machine, manufacturer_model_name, image_array, shape, errorseries
def readdcmfile(filename): """ This function used to read information from dicom file. Input: filename: file path to dicom file. Returns: spacing, machine, image_array, shape Note.: SimpleITK read image in the order of z-y-x, namely the number of slice-width-height; However,SimpleITK read origin and spacing in the order of x-y-z. """ image = ReadImage(filename) machine = image.GetMetaData('0008|0070') manufacturer_model_name = image.GetMetaData('0008|1090') image_array = GetArrayFromImage(image) # in the order of z, y, x shape = image.GetSize() # origin = image.GetOrigin() # in the order of x, y, z spacing = image.GetSpacing() # in the order of x, y, z return spacing, machine, manufacturer_model_name, image_array, shape
def load_itk(filename): """ This function reads a '.mhd' file using SimpleITK and return the image array, origin and spacing of the image. """ # Reads the image using SimpleITK itk_image = ReadImage(filename) # Convert the image to a numpy array first and then # shuffle the dimensions to get axis in the order z,y,x ct_scan = GetArrayFromImage(itk_image) # Read the origin of the ct_scan, will be used to convert # the coordinates from world to voxel and vice versa. origin = np.array(list(reversed(itk_image.GetOrigin()))) # Read the spacing along each dimension spacing = np.array(list(reversed(itk_image.GetSpacing()))) return ct_scan, origin, spacing
def openfiles(self): if self.file_path == "": return if self.name == "": if "T2" in self.file_path.split("/")[-1]: self.name = "T2" if "LGE" in self.file_path.split("/")[-1]: self.name = "LGE" if "C0" in self.file_path.split("/")[-1]: self.name = "C0" if self.name == "": self.name = "C0" itk_img = ReadImage(self.file_path) img = GetArrayFromImage(itk_img) self.spacing = itk_img.GetSpacing() self.direction = itk_img.GetDirection() # print("img:", self.file_path, "direction:", self.direction) self.origin = itk_img.GetOrigin() minDim = list(img.shape).index(min(img.shape)) if minDim == 0: self.img = np.zeros((img.shape[1], img.shape[2], min(img.shape))) for i in range(min(img.shape)): self.img[:, :, i] = self.showRoate(img[i, :, :]) if minDim == 1: self.img = np.zeros((img.shape[0], img.shape[2], min(img.shape))) for i in range(min(img.shape)): self.img[:, :, i] = img[:, i, :] if minDim == 2: self.img = img self.imgDim = self.img.shape[2] if self.imgDim >= 3: self.imgIndex = int(self.imgDim / 2 + 1) else: self.imgIndex = int(self.imgDim / 2) self.adjusted = False self.predicted = False self.isOpen = True
def generate_one(image, label, input_shape, patch_size): p = random() # TODO: Obtain patches at abitrary angles if p > 0.66: patch, label = axial_patch_generator(image, label, patch_size) elif p > 0.33: patch, label = coronal_patch_generator(image, label, patch_size) else: patch, label = sagittal_patch_generator(image, label, patch_size) patch = GetArrayFromImage(patch) if random() > 0.5: patch = np.fliplr(patch) if random() > 0.5: patch = np.flipud(patch) patch = resize(patch, input_shape) return patch, label
def lung_segment(path, model_path): name = ImageSeriesReader_GetGDCMSeriesFileNames(path) raw = ReadImage(name) raw = sitk.Cast(raw, sitk.sitkFloat32) raw = sitk.IntensityWindowing(raw, -1024, 1024, 0, 1.0) arr = GetArrayFromImage(raw) prediction = np.zeros_like(arr) arr = arr[..., np.newaxis] net = unet.Unet(layers=3, features_root=32, channels=1, n_class=2, summaries=False) pre = net.predict(model_path, arr, 4) pre = np.argmax(pre, -1) prediction[:, 20:492, 20:492] = pre stride = 50 index = None for z in range(0, prediction.shape[0], stride): for y in range(154, prediction.shape[1], stride): for x in range(105, prediction.shape[2], stride): patch = prediction[z:z + stride, y:y + stride, x:x + stride] ratio = patch.mean() if ratio > 0.95: index = [z + stride // 2, y + stride // 2, x + stride // 2] break if index: break if index: break index.reverse() # print(index) prediction = sitk.GetImageFromArray(prediction) prediction.CopyInformation(raw) prediction = sitk.Cast(prediction, sitk.sitkUInt8) prediction = sitk.ConnectedThreshold(prediction, [index], 1, 1, 1) return prediction
def get_original_image(input_image, img_type="prostaat"): image_path = f"{DATA_PATH}/{input_image}/{img_type}.mhd" return GetArrayFromImage(ReadImage(image_path))
def hash_image(image): return hash(GetArrayFromImage(image).tobytes())
def transform_img(img_path, output_dir, transformix_object): transformed_path = transformix_object.transform_image( img_path, output_dir=output_dir, verbose=False) transformed_img = GetArrayFromImage(ReadImage(transformed_path)) return transformed_img
def hash_image(image): return hash(GetArrayFromImage(image).tostring())
def get_transformed_image(input_img_path, input_transform): transformed_path = input_transform.transform_image( input_img_path, output_dir=TEMP_RESULTS_PATH, verbose=False) return GetArrayFromImage(ReadImage(transformed_path))
all_training_image_names = [ "p102", "p107", "p108", "p109", "p113", "p116", "p117", "p119", "p120", "p123", "p125", "p128", "p129", "p133", "p135" ] all_validation_image_names = ["p137", "p141", "p143", "p144", "p147"] param_file_names = ["translation", "affine", "parameters_test"] param_array = get_param_array(param_file_names) nr_atlas_images = len(all_training_image_names) for valid_img_name in all_validation_image_names: begin_time = time.time() print(f"{valid_img_name} |", end="\t", flush=True) valid_img_path = f"{VALIDATION_DATA_PATH}/{valid_img_name}/mr_bffe.mhd" valid_img = GetArrayFromImage(ReadImage(valid_img_path)) weights = np.zeros(nr_atlas_images) predictions = np.zeros((nr_atlas_images, 86, 333, 271)) for i, atlas_img_name in enumerate(all_training_image_names): print(f"{atlas_img_name}", end="\t", flush=True) atlas_mr_img_path = f"{TRAINING_DATA_PATH}/{atlas_img_name}/mr_bffe.mhd" atlas_pros_img_path = f"{TRAINING_DATA_PATH}/{atlas_img_name}/prostaat.mhd" transform = get_transform(valid_img_path, atlas_mr_img_path) transformed_atlas_mr_img = get_transformed_image( atlas_mr_img_path, transform) predictions[i] = get_transformed_image(atlas_pros_img_path, transform) weights[i] = metrics.nmi(valid_img, transformed_atlas_mr_img) weights = (weights - np.min(weights))**2 prediction = np.zeros((86, 333, 271)) for i in range(nr_atlas_images): prediction += predictions[i] * weights[i]
# param_file_names = ["fast"] param_file_names = ["translation", "affine", "parameters_test"] param_array = get_param_array(param_file_names) ######################################################################################################################## regs = ['registration Dice ' + dirs[i] for i in range(len(dirs))] regs.append('average registration Dice') ress = ['resulting Dice ' + dirs[i] for i in range(len(dirs))] ress.append('average resulting Dice') columns = (['Fixed image (patient)'] + regs + ress + ['Registration Dice Majority Vote']) frame = pd.DataFrame(columns=columns) sh = np.shape( GetArrayFromImage(ReadImage(os.path.join(data_dir, dirs[0], 'mr_bffe.mhd')))) prostate_estm = np.zeros((sh[0], sh[1], sh[2], len(dirs))) for idx, pat in enumerate(dirs): #over patient prostates_estm_pat = np.zeros((sh[0], sh[1], sh[2], len(dirs) - 1)) dices = np.zeros((2 * len(dirs) + 3, 1)) j = 0 mask = np.ones((len(dirs), 1), dtype=bool) for i in range(len(dirs)): #leave one out over the atlases if dirs[i] != pat: #not register patient to itself results_dir = os.path.join(results_dir_start, pat + '_' + dirs[i]) if not os.path.exists(results_dir): os.mkdir(results_dir) pat_pros, before_dice, dice = run_all(pat, dirs[i], False, False) prostates_estm_pat[:, :, :, j] = pat_pros dices[i] = before_dice dices[i + len(dirs) + 1] = dice