def itk_to_vtk_image(key, itk_image): dims = list(itk_image.GetLargestPossibleRegion().GetSize()) extent = [] for v in dims: extent.append(0) extent.append(v - 1) values = itk.GetArrayFromImage(itk_image).flatten(order='C') return { 'vtkClass': 'vtkImageData', 'spacing': list(itk_image.GetSpacing()), 'origin': list(itk_image.GetOrigin()), 'extent': extent, 'direction': list( itk.GetArrayFromVnlMatrix(itk_image.GetDirection().GetVnlMatrix(). as_matrix()).flatten()), 'pointData': { 'values': values, 'dataType': _itk_image_to_type(itk_image), 'numberOfComponents': itk_image.GetNumberOfComponentsPerPixel(), }, }
def check_same_geometry(img1, img2): origin1 = img1.GetOrigin() origin2 = img2.GetOrigin() if not np.allclose(origin1, origin2): raise TypeError( f'images have incompatible origins: {origin1} versus {origin2}') spacing1 = img1.GetSpacing() spacing2 = img2.GetSpacing() if not np.allclose(spacing1, spacing2): raise TypeError( f'images have incompatible spacing: {spacing1} versus {spacing2}') dire1 = itk.GetArrayFromVnlMatrix( img1.GetDirection().GetVnlMatrix().as_matrix()) dire2 = itk.GetArrayFromVnlMatrix( img2.GetDirection().GetVnlMatrix().as_matrix()) if not np.allclose(dire1, dire2): raise TypeError( f'images have incompatible origins: {dire1} versus {dire2}')
def itk_to_vtkjs_image(itk_image, name='Default Name'): dims = list(itk_image.GetLargestPossibleRegion().GetSize()) extent = [] for v in dims: extent.append(0) extent.append(v - 1) values = itk.GetArrayFromImage(itk_image).flatten(order='C').tolist() return { 'vtkClass': 'vtkImageData', 'name': name, 'dataDescription': 8, # StructuredData.XYZ_GRID from vtk.js 'spacing': list(itk_image.GetSpacing()), 'origin': list(itk_image.GetOrigin()), 'direction': list( itk.GetArrayFromVnlMatrix(itk_image.GetDirection().GetVnlMatrix(). as_matrix()).flatten()), 'extent': extent, 'pointData': { 'vtkClass': 'vtkDataSetAttributes', 'activeScalars': 0, 'arrays': [{ 'data': { 'vtkClass': 'vtkDataArray', 'dataType': _itk_image_to_type(itk_image), 'name': 'Scalars', 'numberOfComponents': itk_image.GetNumberOfComponentsPerPixel(), 'rangeTuple': [0, 255], # TODO range of data 'size': len(values), 'values': values, }, }], }, }
3) # For mem check in dynamic analysis # VNL Vectors v1 = itk.vnl_vector.D(2) v1.fill(1) v_np = itk.GetArrayFromVnlVector(v1) assert v1.get(0) == v_np[0] v_np[0] = 0 assert v1.get(0) != v_np[0] view = itk.GetArrayViewFromVnlVector(v1) 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)
def _convert_itk_matrix_to_numpy(self, M): return itk.GetArrayFromVnlMatrix(M.GetVnlMatrix().as_matrix())
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 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))
def main(args): img_filenames = [] with open(args.csv) as csvfile: csv_reader = csv.DictReader(csvfile) row_keys = csv_reader.fieldnames.copy() for row in csv_reader: img_filenames.append(row[args.img_col]) if(len(img_filenames) > 0): InputPixelType = itk.F InputImageType = itk.Image[InputPixelType, 2] img_read = itk.ImageFileReader[InputImageType].New(FileName=img_filenames[0]) img_read.Update() img = img_read.GetOutput() PixelType = itk.template(img)[1][0] OutputImageType = itk.Image[PixelType, 2] PixelType = itk.template(img)[1][0] OutputImageType = itk.Image[PixelType, 3] InputImageType = itk.Image[PixelType, 2] tileFilter = itk.TileImageFilter[InputImageType, OutputImageType].New() layout = [1, 1, 0] tileFilter.SetLayout(layout) imgs_arr_description = [] for i, filename in enumerate(img_filenames): print("Reading:", filename) img_read = itk.ImageFileReader[InputImageType].New(FileName=filename) img_read.Update() img = img_read.GetOutput() tileFilter.SetInput(i, img) 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_filename"] = os.path.basename(filename) imgs_arr_description.append(img_obj_description) defaultValue = 0 tileFilter.SetDefaultPixelValue(defaultValue) tileFilter.Update() writer = itk.ImageFileWriter[OutputImageType].New() writer.SetFileName(args.out) writer.SetInput(tileFilter.GetOutput()) writer.Update() with open(os.path.splitext(args.out)[0] + ".json", "w") as f: f.write(json.dumps(imgs_arr_description))
def ReadRTDicom(rtPath, image, ContourList): pointXYZ = [] UNReadALL = False if len(ContourList) != 0: UNReadALL = True ContourList = [string.upper() for string in ContourList] # origin spacing origin = image.GetOrigin() spacing = image.GetSpacing() size = image.GetLargestPossibleRegion().GetSize() index = image.GetLargestPossibleRegion().GetIndex() # get the rotation matrix and the inverse directionMatrix = itk.GetArrayFromVnlMatrix( image.GetDirection().GetVnlMatrix().as_matrix()) rotMat = np.zeros(9) rotMatInv = np.zeros(9) for i in range(3): for j in range(3): rotMat[i * 3 + j] = directionMatrix[i, j] rotMatInv[i * 3 + j] = directionMatrix[j, i] #read RT rtdcm_ds = pydicom.read_file(rtPath, force=True) #校验 RT try: ROIContourSequenceA = rtdcm_ds[0x3006, 0x0039].value StructureSetROISequenceA = rtdcm_ds[0x3006, 0x0020].value except Exception: print( 'Problem locating [0x3006,0x0020],[0x3006, 0x0039] - Is this a valid RT Structure file? ' ) return # loop through structures ROI = {} DirOfNumStructureSetROIA = {} DirOfNumROIContourA = {} for StructureSetROI, ROIContour in zip(StructureSetROISequenceA, ROIContourSequenceA): try: DirOfNumStructureSetROIA[StructureSetROI[ 0x3006, 0x0022].value] = StructureSetROI DirOfNumROIContourA[ROIContour[0x3006, 0x0084].value] = ROIContour except Exception: print( 'Problem locating [0x3006, 0x0022],[0x3006, 0x0084] - Is this a valid RT Structure file? ' ) return for ROIContour in ROIContourSequenceA: try: StructureSetROI = DirOfNumStructureSetROIA[ROIContour[ 0x3006, 0x0084].value] OrganName = StructureSetROI[0x3006, 0x0026].value if UNReadALL and (OrganName.upper() not in ContourList): continue except Exception: print( 'Problem locating [0x3006, 0x0026],[0x3006, 0x0084] - Is this a valid RT Structure file? ' ) return # vtkPoly contours contours = vtk.vtkPolyData() # now loop through each item or this structure # eg one prostate region on a single slice is an item cell = vtk.vtkCellArray() points = vtk.vtkPoints() pointId = 0 try: # loop for this organ for roi in ROIContour[0x3006, 0x0040].value: polyLine = vtk.vtkPolyLine() data = np.array(roi[0x3006, 0x0050].value) npts = len(data) // 3 for j in range(npts): p = [ float(data[j * 3 + 0]), float(data[j * 3 + 1]), float(data[j * 3 + 2]) ] # consider the direction p = linearTransform(rotMat, origin, p) pointXYZ.append(p) pointId = points.InsertNextPoint(p) polyLine.GetPointIds().InsertNextId(pointId) # start connected to end p = [float(data[0]), float(data[1]), float(data[2])] # consider the direction p = linearTransform(rotMat, origin, p) pointId = points.InsertNextPoint(p) polyLine.GetPointIds().InsertNextId(pointId) cell.InsertNextCell(polyLine) except Exception as e: print(e) print( 'Problem locating [0x3006, 0x0050],[0x3006, 0x0040] - Is this a valid RT Structure file? ' ) return contours.SetPoints(points) contours.SetLines(cell) contours.Modified() # get bounds bounds = list(contours.GetBounds()) # roi origin spacing size for X Xmin = numpy.floor((bounds[0] - origin[0]) / spacing[0]) - 1 Xmax = numpy.floor((bounds[1] - origin[0]) / spacing[0]) + 2 Xextent = Xmax - Xmin originX = Xmin * spacing[0] + origin[0] # roi origin spacing size for Y Ymin = numpy.floor((bounds[2] - origin[1]) / spacing[1]) - 1 Ymax = numpy.floor((bounds[3] - origin[1]) / spacing[1]) + 2 Yextent = Ymax - Ymin originY = Ymin * spacing[1] + origin[1] # roi origin spacing size for Z Zmin = numpy.floor((bounds[4] - origin[2]) / spacing[2]) - 1 Zmax = numpy.floor((bounds[5] - origin[2]) / spacing[2]) + 2 Zextent = Zmax - Zmin originZ = Zmin * spacing[2] + origin[2] originRoi = [originX, originY, originZ] sizeRoi = [Xextent + 1, Yextent + 1, Zextent + 1] # convert the contours to itkImage #print('contours points number: ', contours.GetNumberOfPoints()) #print('contours cells number: ', contours.GetNumberOfCells()) if contours.GetNumberOfPoints() == 0: continue # prepare the binary image 's voxel grid whiteImage = vtk.vtkImageData() whiteImage.SetSpacing(spacing) whiteImage.SetExtent(0, int(sizeRoi[0]) - 1, 0, int(sizeRoi[1]) - 1, 0, int(sizeRoi[2]) - 1) whiteImage.SetOrigin(originRoi) whiteImage.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1) # vtkIdType count = whiteImage.GetNumberOfPoints() whiteImage.GetPointData().GetScalars().Fill(1) # polygonal data --> image stencil: pol2stenc = vtk.vtkPolyDataToImageStencil() pol2stenc.SetTolerance( 0) # important if extruder->SetVector(0, 0, 1) !!! pol2stenc.SetInputData(contours) pol2stenc.SetOutputOrigin(originRoi) pol2stenc.SetOutputSpacing(spacing) pol2stenc.SetOutputWholeExtent(whiteImage.GetExtent()) pol2stenc.Update() # cut the corresponding white image and set the background: imgstenc = vtk.vtkImageStencil() imgstenc.SetInputData(whiteImage) imgstenc.SetStencilData(pol2stenc.GetOutput()) imgstenc.ReverseStencilOff() imgstenc.SetBackgroundValue(0) imgstenc.Update() imageOrganVtk = imgstenc.GetOutput() # vtk image to numpy and to itk rows, cols, pages = imageOrganVtk.GetDimensions() imageNp = vtk_to_numpy(imageOrganVtk.GetPointData().GetScalars()) imageNp = numpy.ascontiguousarray( imageNp.reshape(pages, cols, rows) * 255) # assert imageNp.shape == imageOrganVtk.GetDimensions() imageOrganItk = itk.GetImageFromArray(imageNp) imageOrganItk.SetSpacing(imageOrganVtk.GetSpacing()) # for origin direction is considered originRoi = imageOrganVtk.GetOrigin() originRoi = linearTransform(rotMatInv, origin, originRoi) imageOrganItk.SetOrigin(originRoi) # direction imageOrganItk.SetDirection(image.GetDirection()) # image push back ROI[OrganName] = imageOrganItk return ROI, pointXYZ