def vtk_to_itk_image(key, vtk_image): pixel_data = vtk_image['pointData']['values'] pixel_type = vtk_image['pointData']['dataType'] pixel_data = _vtkjs_type_convert(pixel_data, pixel_type) # numpy indexes in ZYX order, where X varies the fastest dims = [ vtk_image['extent'][5] - vtk_image['extent'][4] + 1, vtk_image['extent'][3] - vtk_image['extent'][2] + 1, vtk_image['extent'][1] - vtk_image['extent'][0] + 1, ] direction = np.zeros((3, 3)) for x in range(3): for y in range(3): direction[x][y] = vtk_image['direction'][x * 3 + y] itkImage = itk.GetImageFromArray(np.reshape(pixel_data, dims)) # https://discourse.itk.org/t/set-image-direction-from-numpy-array/844/10 vnlmat = itk.GetVnlMatrixFromArray(direction) itkImage.GetDirection().GetVnlMatrix().copy_in(vnlmat.data_block()) itkImage.SetOrigin(vtk_image['origin']) itkImage.SetSpacing(vtk_image['spacing']) return itkImage
def read_3d_dicom(dicomFile, flip=False): """ Read dicom file and return an float 3D image """ files = [] files.append(pydicom.read_file(dicomFile[0])) # skip files with no SliceLocation (eg scout views) slices = [] if len(files) == 1: slices.append(files[0]) else: logger.error('no file available') return dicomProperties = dicom_properties() dicomProperties.read_dicom_properties(slices[0]) # create 3D array if len(slices[0].pixel_array.shape) == 2: dicomProperties.img_shape = [1] + dicomProperties.img_shape img3d = np.zeros(dicomProperties.img_shape) # fill 3D array with the images from the files if len(slices[0].pixel_array.shape) == 2: img3d[0, :, :] = slices[0].pixel_array else: img3d[:, :, :] = slices[0].pixel_array img3d = dicomProperties.rs * img3d + dicomProperties.ri img_result = itk.image_from_array(np.float32(img3d)) img_result.SetSpacing(dicomProperties.spacing) img_result.SetOrigin(dicomProperties.origin) arrayDirection = np.zeros([3, 3], np.float64) arrayDirection[0, 0] = dicomProperties.io[0] arrayDirection[0, 1] = dicomProperties.io[1] arrayDirection[0, 2] = dicomProperties.io[2] arrayDirection[1, 0] = dicomProperties.io[3] arrayDirection[1, 1] = dicomProperties.io[4] arrayDirection[1, 2] = dicomProperties.io[5] arrayDirection[2, :] = np.cross(arrayDirection[0, :], arrayDirection[1, :]) if Tag(0x18, 0x88) in slices[0] and slices[0][0x18, 0x88].value < 0: arrayDirection[2, 2] = -1.0 else: flip = False arrayDirection[2, 2] = 1.0 matrixItk = itk.Matrix[itk.D, 3, 3](itk.GetVnlMatrixFromArray(arrayDirection)) img_result.SetDirection(matrixItk) if flip: flipFilter = itk.FlipImageFilter.New(Input=img_result) flipFilter.SetFlipAxes((False, False, True)) flipFilter.SetFlipAboutOrigin(False) flipFilter.Update() img_result = flipFilter.GetOutput() return img_result
def vtkjs_to_itk_image(vtkObject): if vtkObject['vtkClass'] == 'vtkImageData': imgArr = vtkObject['pointData']['arrays'][0]['data']['values'] # numpy indexes in ZYX order, where X varies the fastest dims = [ vtkObject['extent'][5] - vtkObject['extent'][4] + 1, vtkObject['extent'][3] - vtkObject['extent'][2] + 1, vtkObject['extent'][1] - vtkObject['extent'][0] + 1, ] direction = np.zeros((3, 3)) # why the direction is a json object instead of an array, nobody knows... # (actually I think it's b/c "direction" is stored as a Float32Array in vtkjs) for x in range(3): for y in range(3): direction[x][y] = vtkObject['direction'][str(x * 3 + y)] itkImage = itk.GetImageFromArray(np.reshape(imgArr, dims)) # https://discourse.itk.org/t/set-image-direction-from-numpy-array/844/10 vnlmat = itk.GetVnlMatrixFromArray(direction) itkImage.GetDirection().GetVnlMatrix().copy_in(vnlmat.data_block()) itkImage.SetOrigin(vtkObject['origin']) itkImage.SetSpacing(vtkObject['spacing']) return itkImage return None
assert v1.get(0) == view[0] view[0] = 0 assert v1.get(0) == view[0] # VNL Matrices m1 = itk.vnl_matrix.D(2, 2) m1.fill(1) m_np = itk.GetArrayFromVnlMatrix(m1) assert m1.get(0, 0) == m_np[0, 0] m_np[0, 0] = 0 assert m1.get(0, 0) != m_np[0, 0] view = itk.GetArrayViewFromVnlMatrix(m1) assert m1.get(0, 0) == view[0, 0] view[0, 0] = 0 assert m1.get(0, 0) == view[0, 0] arr = np.zeros([3, 3]) m_vnl = itk.GetVnlMatrixFromArray(arr) assert m_vnl(0, 0) == 0 m_vnl.put(0, 0, 3) assert m_vnl(0, 0) == 3 assert arr[0, 0] == 0 # ITK Matrix arr = np.zeros([3, 3], float) m_itk = itk.GetMatrixFromArray(arr) # Test snake case function m_itk = itk.matrix_from_array(arr) m_itk.SetIdentity() # Test that the numpy array has not changed,... assert arr[0, 0] == 0 # but that the ITK matrix has the correct value. assert m_itk(0, 0) == 1 arr2 = itk.GetArrayFromMatrix(m_itk)
np_copy = itk.GetArrayFromImage(itk_image) #do numpy stuff #convert back to itk, view only, data is not copied itk_np_view = itk.GetImageViewFromArray(np_copy) #convert back to itk, data is not copied itk_np_copy = itk.GetImageFromArray(np_copy) # Save result itk.imwrite(itk_np_view, output_filename) # Vnl matrix[View] from array arr = np.zeros([3, 3], np.uint8) matrix_view = itk.GetVnlMatrixViewFromArray(arr) matrix = itk.GetVnlMatrixFromArray(arr) # Array[View] from Vnl matrix arr_view = itk.GetArrayViewFromVnlMatrix(matrix) arr = itk.GetArrayFromVnlMatrix(matrix) # Vnl vector[View] from array vec = np.zeros([3], np.uint8) vnl_vector_view = itk.GetVnlVectorViewFromArray(vec) vnl_vector = itk.GetVnlVectorFromArray(vec) # Array[View] from Vnl vector vec_view = itk.GetArrayViewFromVnlVector(vnl_vector) vec = itk.GetArrayFromVnlVector(vnl_vector)
def read_dicom(dicomFiles): """ Read dicom files and return an float 3D image """ files = [] #Load dicom files for file in dicomFiles: try: files.append(pydicom.read_file(file)) except pydicom.errors.InvalidDicomError: ds = pydicom.read_file(file, force=True) ds.file_meta.TransferSyntaxUID = pydicom.uid.ImplicitVRLittleEndian files.append(ds) # skip files with no SliceLocation (eg scout views) slices = [] skipcount = 0 if len(files) > 1: for f in files: if hasattr(f, 'SliceLocation') or hasattr(f, 'ImagePositionPatient'): slices.append(f) else: skipcount = skipcount + 1 if skipcount > 0: logger.info("skipped, no SliceLocation: {}".format(skipcount)) # ensure they are in the correct order. Sort according Image Position along z slices = sorted(slices, key=lambda s: s[0x0020, 0x0032][2]) else: logger.error('no file available') return if len(slices) == 0: logger.error('no slice available') return dicomProperties = dicom_properties() if len(slices) >= 2: dicomProperties.read_dicom_properties(slices[0], slices[1]) else: dicomProperties.read_dicom_properties(slices[0]) # create 3D array dicomProperties.img_shape[0] = len(slices) dicomProperties.img_shape.append(slices[0].pixel_array.shape[0]) img3d = np.zeros(dicomProperties.img_shape) # fill 3D array with the images from the files for i, s in enumerate(slices): img2d = s.pixel_array dicomPropertiesSlice = dicom_properties() dicomPropertiesSlice.read_dicom_slop_intercept(s) img3d[ i, :, :] = dicomPropertiesSlice.rs * img2d + dicomPropertiesSlice.ri img_result = itk.image_from_array(np.float32(img3d)) img_result.SetSpacing(dicomProperties.spacing) img_result.SetOrigin(dicomProperties.origin) arrayDirection = np.zeros([3, 3], np.float64) arrayDirection[0, 0] = dicomProperties.io[0] arrayDirection[0, 1] = dicomProperties.io[1] arrayDirection[0, 2] = dicomProperties.io[2] arrayDirection[1, 0] = dicomProperties.io[3] arrayDirection[1, 1] = dicomProperties.io[4] arrayDirection[1, 2] = dicomProperties.io[5] arrayDirection[2, :] = np.cross(arrayDirection[0, :], arrayDirection[1, :]) matrixItk = itk.Matrix[itk.D, 3, 3](itk.GetVnlMatrixFromArray(arrayDirection)) img_result.SetDirection(matrixItk) return img_result
def main(args): if (args.json): imgs_arr = [] for img_index, img_filename in enumerate(args.img): img_read = itk.ImageFileReader.New(FileName=img_filename) img_read.Update() img = img_read.GetOutput() imgs_arr.append(img) description_arr = [] with open(args.json, "r") as jsf: description_arr = json.load(jsf) for img in imgs_arr: img_np = itk.GetArrayViewFromImage(img) for img_index in range(img_np.shape[0]): description = description_arr[img_index] RegionType = itk.ImageRegion[2] region = RegionType() region.SetIndex(description["image"]["region"]["index"]) region.SetSize(description["image"]["region"]["size"]) PixelType = itk.template(img)[1][0] OutputImageType = itk.Image[PixelType, 2] out_img = OutputImageType.New() out_img.SetRegions(region) out_img.SetOrigin(description["image"]["origin"]) out_img.SetSpacing(description["image"]["spacing"]) np_dir_vnl = itk.GetVnlMatrixFromArray( np.array(description["image"]["direction"])) direction = out_img.GetDirection() direction.GetVnlMatrix().copy_in(np_dir_vnl.data_block()) out_img.Allocate() out_img_np = itk.GetArrayViewFromImage(out_img) out_img_np.setfield(img_np[img_index], out_img_np.dtype) if (not os.path.exists(args.out) or not os.path.isdir(args.out)): os.makedirs(args.out) out_filename = os.path.join(args.out, description["img_filename"]) print("Writing:", out_filename) writer = itk.ImageFileWriter.New(FileName=out_filename, Input=out_img) writer.Update() else: imgs_arr = [] imgs_arr_description = [] csv_headers = [] if args.out_csv_headers: csv_headers = args.out_csv_headers for img_index, img_filename in enumerate(args.img): img_read = itk.ImageFileReader.New(FileName=img_filename) img_read.Update() img = img_read.GetOutput() imgs_arr.append(img) if args.out_csv_headers is None: csv_headers.append(img_index) img_obj_description = {} img_obj_description["image"] = {} img_obj_description["image"]["region"] = {} img_obj_description["image"]["region"]["size"] = np.array( img.GetLargestPossibleRegion().GetSize()).tolist() img_obj_description["image"]["region"]["index"] = np.array( img.GetLargestPossibleRegion().GetIndex()).tolist() img_obj_description["image"]["spacing"] = np.array( img.GetSpacing()).tolist() img_obj_description["image"]["origin"] = np.array( img.GetOrigin()).tolist() img_obj_description["image"][ "direction"] = itk.GetArrayFromVnlMatrix( img.GetDirection().GetVnlMatrix().as_matrix()).tolist() img_obj_description["img_index"] = img_index img_obj_description["img_filename"] = img_filename img_obj_description["slice"] = {} imgs_arr_description.append(img_obj_description) if len(args.img) != len(csv_headers): print( "The csv headers provided do not have the same length as the number of images provided", file=sys.stderr) sys.exit(1) if len(imgs_arr) == 0: print("You need to provide at least one image!", file=sys.stderr) sys.exit(1) print(imgs_arr_description) img_np = itk.GetArrayViewFromImage(imgs_arr[0]) img_shape_max = np.max(img_np.shape) out_size = np.array([img_shape_max, img_shape_max]).tolist() PixelType = itk.template(imgs_arr[0])[1][0] OutputImageType = itk.Image[PixelType, 2] out_csv_rows = [] if imgs_arr[0].GetImageDimension() == 3: img_shape = img_np.shape for dim in range(imgs_arr[0].GetImageDimension()): imgs_arr_description[img_index]["slice"][dim] = [] for sln in range(img_shape[dim]): start = [0, 0, 0] end = [None, None, None] start[dim] = sln end[dim] = sln + 1 uuid_out_name = str(uuid.uuid4()) out_obj_csv = {} for img_index, img in enumerate(imgs_arr): img_np = itk.GetArrayViewFromImage(img) img_np_2d = np.squeeze(img_np[start[0]:end[0], start[1]:end[1], start[2]:end[2]], axis=dim) size_np = img_np_2d.shape img_np_2d_max_size = np.zeros(out_size) img_np_2d_max_size[0:size_np[0], 0:size_np[1]] = img_np_2d index = itk.Index[2]() index.Fill(0) RegionType = itk.ImageRegion[2] region = RegionType() region.SetIndex(index) region.SetSize(out_size) out_img = OutputImageType.New() out_img.SetRegions(region) out_img.SetOrigin( np.delete(img.GetOrigin(), dim).tolist()) out_img.SetSpacing( np.delete(img.GetSpacing(), dim).tolist()) out_img.Allocate() out_img_np = itk.GetArrayViewFromImage(out_img) out_img_np.setfield(img_np_2d_max_size, out_img_np.dtype) out_dir = os.path.join(args.out, str(csv_headers[img_index])) if (not os.path.exists(out_dir) or not os.path.isdir(out_dir)): os.makedirs(out_dir) out_filename = os.path.join(out_dir, uuid_out_name + ".nrrd") print("Writing:", out_filename) writer = itk.ImageFileWriter.New(FileName=out_filename, Input=out_img) writer.Update() out_obj_csv[csv_headers[img_index]] = out_filename imgs_arr_description[img_index]["slice"][dim].append( out_filename) out_csv_rows.append(out_obj_csv) with open(args.out_csv, "w") as f: writer = csv.DictWriter(f, fieldnames=csv_headers) writer.writeheader() for row in out_csv_rows: writer.writerow(row) if (args.json_desc): with open(args.json_desc, "w") as f: f.write(json.dumps(imgs_arr_description))