def get_obb_from_points(points): from pyobb.obb import OBB """ Args: points:(N,3) [x,y,z] Returns: correct_box: (7,) [x_hat, y_hat, z_hat, dx_hat, dy_hat, dz_hat, yaw_hat] """ obb = OBB.build_from_points(points) x_hat, y_hat, z_hat = obb.centroid[0], obb.centroid[1], obb.centroid[2] dx_hat, dy_hat, dz_hat = obb.extents[0] * 2, obb.extents[ 1] * 2, obb.extents[2] * 2 yaw_hat = np.arctan2(obb.rotation[0, 2], obb.rotation[2, 2]) + np.pi / 2 return np.array([x_hat, y_hat, z_hat, dx_hat, dy_hat, dz_hat, yaw_hat])
def min_area_mask(mask): none_zero_idx = np.where(mask == 1) poses = [] for i in range(len(none_zero_idx[0])): poses.append( [none_zero_idx[0][i], none_zero_idx[1][i], none_zero_idx[2][i]]) # poses = np.array(poses) obb = OBB.build_from_points(poses) min_idx = np.round(obb.min).astype(int) max_idx = np.round(obb.max).astype(int) cube_mask = np.zeros(mask.shape) cube_mask[min_idx[0]:max_idx[0], min_idx[1]:max_idx[1], min_idx[2]:max_idx[2]] = 1 return cube_mask
def compute_obb(coords, return_max=False): obb = OBB.build_from_points(coords) min_xyz = obb.min max_xyz = obb.max centroid = obb.centroid rotation = obb.rotation points = obb.points # combined_index = [] # for i in itertools.combinations(range(7), 4): # combined_index.append([i[0], i[1], i[2], i[3]]) # combined_xyz = [[points[index[i]] # for i in range(4)] for index in combined_index] # count = 0 # mean_centroid = [] # for xyz in combined_xyz: # if same_plane(xyz): # mean_centroid.append(np.mean(np.array(xyz), axis=0)) if return_max: return points, [min_xyz, max_xyz] return points
def main(args): # Read image labelPath = Path(args.imagePath) / (args.prefix + "segmentation.nii.gz") imagePath = Path(args.imagePath) / (args.prefix + "imaging.nii.gz") print("Reading {}...".format(str(labelPath))) print("Reading {}...".format(str(imagePath))) img = sitk.ReadImage(str(imagePath)) imageArray = sitk.GetArrayFromImage(img) label = sitk.ReadImage(str(labelPath)) labelArray = sitk.GetArrayFromImage(label) # Find a border dividing the kidney into a separate space startIdx, endIdx = searchBound(labelArray, 'sagittal') print("startIndex : ", startIdx) print("endIndex : ", endIdx) # Divide the kidney into leftArray and rightArray leftArray = np.copy(labelArray[ : startIdx[1] - 1, :, :]) rightArray = np.copy(labelArray[endIdx[0] + 1 : , :, :]) print('leftArray shapes : ', leftArray.shape) print('rightArray shapes : ', rightArray.shape) leftImgArray = np.copy(imageArray[ : startIdx[1] - 1,:,:]) rightImgArray = np.copy(imageArray[endIdx[0] + 1 : , :, :]) arrayDict = {"left" : np.array([np.copy(leftArray), np.copy(leftImgArray)]), "right" : np.array([np.copy(rightArray), np.copy(rightImgArray)])} del imageArray, labelArray, leftArray, leftImgArray, rightArray, rightImgArray gc.collect() for xxx in ["left", "right"]: # Input array inputLabelArray = arrayDict[xxx][0] inputImageArray = arrayDict[xxx][1] # Find kidney region idx = np.where(inputLabelArray > 0) # Preprocessing for OBB vertics = np.stack([*idx], axis=-1) # Implement OBB obb = OBB.build_from_points(vertics) # Minimum vertics for defining bounding box per vertex index = (((0, 1), (0, 3), (0, 5)), ((1, 0), (1, 2), (1, 4)), ((2, 1), (2, 3), (2, 7)), ((3, 0), (3, 2), (3, 6)), ((4, 1), (4, 5), (4, 7)), ((5, 0), (5, 4), (5, 6)), ((6, 3), (6, 5), (6, 7)), ((7, 2,), (7, 4), (7, 6))) # Find the closest vertex to origin minVertex = sorted([(x[0]**2 + x[1]**2 + x[2]**2, i) for i, x in enumerate(obb.points)])[0][1] print("minVertex : ", minVertex) # Calucualte the length of each side of bouding box and output in decending order points = getSortedDistance(obb.points, index[minVertex]) #Slide to locate point[0][0] into (0,0,0) #points = points - points[0][0] rotationMatrix, rotatedBoundingVertics = makeCompleteMatrix(points) print("rotatedBoundingVertics") print(rotatedBoundingVertics.astype(int)) #Measure for rotated coordinates are out of range of inputArray size slide, affineMatrix = determineSlide(rotatedBoundingVertics, rotationMatrix, inputLabelArray) # Slide boundingVertics print("slide : ", slide) rotatedAndSlidedBoundingVertics = rotatedBoundingVertics + slide print("rotatedAndSlidedBoundingVertics") print(rotatedAndSlidedBoundingVertics.astype(int)) origin, clipSize = determineClipSize(rotatedAndSlidedBoundingVertics, inputLabelArray.shape) print("origin : ", origin) print("clipSize : ", clipSize) # For affine transformation, make inverse matrix invAffine = np.linalg.inv(affineMatrix) refCoords = makeRefCoords(inputLabelArray, invAffine) print("redCoords shape : ", refCoords.shape) print("Rotating image...") rotatedLabelArray = transformImageArray(inputLabelArray, refCoords, "nearest") rotatedImageArray = transformImageArray(inputImageArray, refCoords, "linear") rotatedLabelArray = rotatedLabelArray[origin[0] - 1 : clipSize[0] + 1, origin[1] - 1 : clipSize[1] + 1, origin[2] - 1 : clipSize[2] + 1] rotatedImageArray = rotatedImageArray[origin[0] - 1 : clipSize[0] + 1, origin[1] - 1 : clipSize[1] + 1, origin[2] - 1 : clipSize[2] + 1] pre = np.where(inputLabelArray > 0, True, False).sum() post = np.where(rotatedLabelArray > 0, True, False).sum() log = Path(args.log) / "failList.txt" saveLabelPath = Path(args.savePath) / ("label_" + xxx + "." + args.extension) saveImagePath = Path(args.savePath) / ("image_" + xxx + "." + args.extension) createParentPath(saveLabelPath) # reverse right image if xxx == "right": print("It is the right kidney which should be reversed.") rotatedLabelArray = reverseImage(rotatedLabelArray) rotatedImageArray = reverseImage(rotatedImageArray) if 0.99 < post / pre < 1.1: print("Succeeded in clipping.") rotatedLabel = sitk.GetImageFromArray(rotatedLabelArray) rotatedImage = sitk.GetImageFromArray(rotatedImageArray) saveImage(rotatedLabel, label, str(saveLabelPath)) saveImage(rotatedImage, img, str(saveImagePath)) else: print("Failed to clip.") print("Writing failed patient to {}".format(str(log))) print("Done") # Match one kidney shape with the other one. if (Path(args.savePath) / ("label_right." + args.extension)).exists() and (Path(args.savePath) / ("label_left." + args.extension)).exists(): rightLabelPath = Path(args.savePath) / ("label_right." + args.extension) rightImagePath = Path(args.savePath) / ("image_right." + args.extension) leftLabelPath = Path(args.savePath) / ("label_left." + args.extension) leftImagePath = Path(args.savePath) / ("image_left." + args.extension) rightLabel = sitk.ReadImage(str(rightLabelPath)) rightImage = sitk.ReadImage(str(rightImagePath)) leftLabel = sitk.ReadImage(str(leftLabelPath)) leftImage = sitk.ReadImage(str(leftImagePath)) rightLabelArray = sitk.GetArrayFromImage(rightLabel) rightImageArray = sitk.GetArrayFromImage(rightImage) leftLabelArray = sitk.GetArrayFromImage(leftLabel) leftImageArray = sitk.GetArrayFromImage(leftImage) rightLabelTransformedArray = Resizing(rightLabelArray, leftLabelArray,"nearest") rightImageTransformedArray = Resizing(rightImageArray, leftImageArray, "linear") leftLabelTransformedArray = Resizing(leftLabelArray, rightLabelArray,"nearest") leftImageTransformedArray = Resizing(leftImageArray, rightImageArray, "linear") saveRightLabelTransformedPath = Path(args.savePath) / ("label_right_transformed." + args.extension) saveRightImageTransformedPath = Path(args.savePath) / ("image_right_transformed." + args.extension) saveLeftLabelTransformedPath = Path(args.savePath) / ("label_left_transformed." + args.extension) saveLeftImageTransformedPath = Path(args.savePath) / ("image_left_transformed." + args.extension) rightLabelTransformed = sitk.GetImageFromArray(rightLabelTransformedArray) rightImageTransformed = sitk.GetImageFromArray(rightImageTransformedArray) leftLabelTransformed = sitk.GetImageFromArray(leftLabelTransformedArray) leftImageTransformed = sitk.GetImageFromArray(leftImageTransformedArray) saveImage(rightLabelTransformed, rightLabel, str(saveRightLabelTransformedPath)) saveImage(rightImageTransformed, rightImage, str(saveRightImageTransformedPath)) saveImage(leftLabelTransformed, leftLabel, str(saveLeftLabelTransformedPath)) saveImage(leftImageTransformed, leftImage, str(saveLeftImageTransformedPath))
from apt_importers import * import numpy as np from pyflann import FLANN from pyobb.obb import OBB from scipy.spatial import ConvexHull from clusters import community_structure fl = FLANN() #import tensorflow as tf #import matplotlib #matplotlib.use('Agg') import matplotlib.pyplot as plt dpos= get_dpos('R12_Al-Sc.epos', 'ranges.rrng') obb = OBB.build_from_points(dpos.loc[:, ['x', 'y', 'z']].values) Sc_pos = dpos.loc[dpos.Element == 'Sc', :] import time t = time.time() pos1, pos2, _ = singleton_removal(Sc_pos, k=10, alpha=0.01) el_time = time.time() - t viz = False if viz is True: cm = plt.get_cmap('gist_rainbow') cmap = np.asarray([cm(1. * i / 2) for i in range(2)]) colors = [np.tile(cmap[0, :], (len(pos1), 1)), np.tile(cmap[1, :], (len(pos2), 1))]
def pipeline(scan, label, obstacle_lst, verbose=False, OBBoxes=False, exec_time=False, **params): """ ROI filtering """ ################################################################################################## start_time = datetime.now() pcloud = pd.DataFrame(np.concatenate((scan, label.reshape(len(label), 1)), axis=1), columns=['x', 'y', 'z', 'seg_id']) pcloud = common.roi_filter(pcloud, min_x=params['roi_x_min'], max_x=params['roi_x_max'], min_y=params['roi_y_min'], max_y=params['roi_y_max'], min_z=params['roi_z_min'], max_z=params['roi_z_max'], verbose=False) roi_time = (datetime.now() - start_time).total_seconds() ################################################################################################### """ Obstacles filtering """ ################################################################################################### start_time = datetime.now() pcloud = common.obstacle_filter(pcloud, obstacle_lst, proc_labels=params['proc_labels'], verbose=False) obstacle_time = (datetime.now() - start_time).total_seconds() ################################################################################################### if len(pcloud) > 200: # Getting voxel grid start_time = datetime.now() voxel_time = (datetime.now() - start_time).total_seconds() """ Сlustering obstacles """ ############################################################################################### start_time = datetime.now() clusterer = DBSCAN(eps=params['eps'], min_samples=params['min_samples'], algorithm='auto', leaf_size=params['leaf_size'], n_jobs=-1) clusterer.fit(pcloud[['x', 'y', 'z']]) pcloud['cluster_id'] = clusterer.labels_ cluster_time = (datetime.now() - start_time).total_seconds() ############################################################################################### """ Getting bounding boxes coord """ ############################################################################################### start_time = datetime.now() pcloud['norm'] = np.sqrt(np.square(pcloud[['x', 'y', 'z']]).sum(axis=1)) cluster_data = pd.DataFrame.from_dict({'x': [], 'y': [], 'z': [],'cluster_id': []}) clusters = [] for _id in pcloud['cluster_id'].unique(): if _id == -1 or len(pcloud[pcloud['cluster_id'] == _id]) < 100 or len(pcloud[pcloud['cluster_id'] == _id]) > 2500: continue tcluster = common.outlier_filter(pcloud[pcloud['cluster_id'] == _id], verbose=False) cluster_data = cluster_data.append(tcluster) if OBBoxes: obb = OBB.build_from_points(tcluster[['x', 'y', 'z']].values) clusters.append([x.tolist() for x in obb.points]) if not OBBoxes: clusters = cluster_data.groupby(['cluster_id']).agg({ 'x': ['min', 'max'], 'y': ['min', 'max'], 'z': ['min', 'max'] }).values bb_time = (datetime.now() - start_time).total_seconds() ############################################################################################### else: clusters, cluster_data = np.empty((0, 0)), np.empty((0, 0)) voxel_time, cluster_time, bb_time = 0, 0, 0 if verbose: print('Execution time:') print('\n - ROI filtering: {:.5f}s'.format(roi_time)) print('\n - Filtering obstacles: {:.5f}s'.format(obstacle_time)) print('\n - Voxel grid: {:.5f}s'.format(voxel_time)) print('\n - Clustering: {:.5f}s'.format(cluster_time)) print('\n - Min-max cluster points: {:.5f}s \n'.format(bb_time)) if exec_time: return clusters, cluster_data, {'roi_time': roi_time, 'filter_obstacle_time': obstacle_time, 'voxel_grid_time': voxel_time, 'clustering_time': cluster_time, 'outlier_filter_bbox_time': bb_time} else: return clusters, cluster_data
def main(): parser = ArgumentParser() parser.add_argument('--obj', type=str, required=True, help='OBJ filename') args = parser.parse_args() init() viewport = (800, 600) display.set_mode(viewport, OPENGL | DOUBLEBUF) display.set_caption('pyobb 3D demo') glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glLightfv(GL_LIGHT0, GL_POSITION, (0, -1, 0, 0)) glLightfv(GL_LIGHT0, GL_AMBIENT, (0.2, 0.2, 0.2, 1)) glLightfv(GL_LIGHT0, GL_DIFFUSE, (0.5, 0.5, 0.5, 1)) glEnable(GL_COLOR_MATERIAL) glEnable(GL_DEPTH_TEST) glShadeModel(GL_SMOOTH) obj = OBJ(filename=args.obj) indices = [] for face in obj.faces: indices.append(face[0][0] - 1) indices.append(face[0][1] - 1) indices.append(face[0][2] - 1) obb = OBB.build_from_triangles(obj.vertices, indices) obb_gl_list = glGenLists(1) glNewList(obb_gl_list, GL_COMPILE) glBegin(GL_LINES) glColor3fv((1, 0, 0)) def input_vertex(x, y, z): glVertex3fv(obb.transform((x, y, z))) input_vertex(*obb.max) input_vertex(obb.max[0], obb.min[1], obb.max[2]) input_vertex(obb.max[0], obb.min[1], obb.max[2]) input_vertex(obb.min[0], obb.min[1], obb.max[2]) input_vertex(obb.min[0], obb.min[1], obb.max[2]) input_vertex(obb.min[0], obb.max[1], obb.max[2]) input_vertex(obb.min[0], obb.max[1], obb.max[2]) input_vertex(*obb.max) input_vertex(obb.max[0], obb.max[1], obb.max[2]) input_vertex(obb.max[0], obb.max[1], obb.min[2]) input_vertex(obb.max[0], obb.min[1], obb.max[2]) input_vertex(obb.max[0], obb.min[1], obb.min[2]) input_vertex(obb.min[0], obb.max[1], obb.max[2]) input_vertex(obb.min[0], obb.max[1], obb.min[2]) input_vertex(obb.min[0], obb.min[1], obb.max[2]) input_vertex(obb.min[0], obb.min[1], obb.min[2]) input_vertex(obb.max[0], obb.max[1], obb.min[2]) input_vertex(obb.max[0], obb.min[1], obb.min[2]) input_vertex(obb.max[0], obb.min[1], obb.min[2]) input_vertex(*obb.min) input_vertex(*obb.min) input_vertex(obb.min[0], obb.max[1], obb.min[2]) input_vertex(obb.min[0], obb.max[1], obb.min[2]) input_vertex(obb.max[0], obb.max[1], obb.min[2]) glEnd() glEndList() clock = time.Clock() glMatrixMode(GL_PROJECTION) glLoadIdentity() width, height = viewport gluPerspective(90.0, width / float(height), 0.1, 100.0) glEnable(GL_DEPTH_TEST) glMatrixMode(GL_MODELVIEW) rotation = [0, 0] translation = [ -obb.centroid[0], -obb.centroid[1], -(obb.centroid[2] + obb.extents[2] * 2) ] rotate = move = False while True: clock.tick(30) for e in event.get(): if e.type == QUIT: exit() elif e.type == KEYDOWN and e.key == K_ESCAPE: exit() elif e.type == MOUSEBUTTONDOWN: if e.button == 4: translation[2] += 0.1 elif e.button == 5: translation[2] -= 0.1 elif e.button == 1: rotate = True elif e.button == 2: move = True elif e.type == MOUSEBUTTONUP: if e.button == 1: rotate = False elif e.button == 2: move = False elif e.type == MOUSEMOTION: i, j = e.rel if rotate: rotation[1] += i rotation[0] += j if move: translation[0] += i * .025 translation[1] -= j * .025 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() glTranslate(translation[0], translation[1], translation[2]) glRotate(rotation[0], 1, 0, 0) glRotate(rotation[1], 0, 1, 0) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glCallList(obj.gl_list) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glCallList(obb_gl_list) display.flip()
def main(): init() viewport = (800, 600) display.set_mode(viewport, OPENGL | DOUBLEBUF) display.set_caption('pyobb 2D demo') clock = time.Clock() glMatrixMode(GL_PROJECTION) glLoadIdentity() width, height = viewport gluOrtho2D(0, width, 0, height) glMatrixMode(GL_MODELVIEW) glLoadIdentity() points = [] render_gl_lists = False while True: clock.tick(30) for e in event.get(): if e.type == QUIT: exit() elif e.type == KEYDOWN: if e.key == K_ESCAPE: exit() elif e.key == K_RETURN: poly_gl_list = glGenLists(1) glNewList(poly_gl_list, GL_COMPILE) glColor3fv((0, 0, 1)) glBegin(GL_POLYGON) for point in points: glVertex2fv(point) glEnd() glEndList() obb = OBB.build_from_points([(point[0], point[1], 0) for point in points]) obb_gl_list = glGenLists(1) glNewList(obb_gl_list, GL_COMPILE) glBegin(GL_LINES) glColor3fv((1, 0, 0)) def input_vertex(x, y, z): glVertex3fv(obb.transform((x, y, z))) input_vertex(*obb.max) input_vertex(obb.max[0], obb.min[1], obb.max[2]) input_vertex(obb.max[0], obb.min[1], obb.max[2]) input_vertex(obb.min[0], obb.min[1], obb.max[2]) input_vertex(obb.min[0], obb.min[1], obb.max[2]) input_vertex(obb.min[0], obb.max[1], obb.max[2]) input_vertex(obb.min[0], obb.max[1], obb.max[2]) input_vertex(*obb.max) input_vertex(obb.max[0], obb.max[1], obb.max[2]) input_vertex(obb.max[0], obb.max[1], obb.min[2]) input_vertex(obb.max[0], obb.min[1], obb.max[2]) input_vertex(obb.max[0], obb.min[1], obb.min[2]) input_vertex(obb.min[0], obb.max[1], obb.max[2]) input_vertex(obb.min[0], obb.max[1], obb.min[2]) input_vertex(obb.min[0], obb.min[1], obb.max[2]) input_vertex(obb.min[0], obb.min[1], obb.min[2]) input_vertex(obb.max[0], obb.max[1], obb.min[2]) input_vertex(obb.max[0], obb.min[1], obb.min[2]) input_vertex(obb.max[0], obb.min[1], obb.min[2]) input_vertex(*obb.min) input_vertex(*obb.min) input_vertex(obb.min[0], obb.max[1], obb.min[2]) input_vertex(obb.min[0], obb.max[1], obb.min[2]) input_vertex(obb.max[0], obb.max[1], obb.min[2]) glEnd() glEndList() render_gl_lists = True elif e.key == K_BACKSPACE: points = [] render_gl_lists = False elif e.type == MOUSEBUTTONDOWN: if e.button == 1: point = mouse.get_pos() points.append((point[0], height - point[1])) elif e.button == 2: points = points[:-1] glClear(GL_COLOR_BUFFER_BIT) glLoadIdentity() if render_gl_lists: glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glCallList(poly_gl_list) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glCallList(obb_gl_list) glPointSize(6.0) glColor3fv((0, 1, 0)) glBegin(GL_POINTS) for point in points: glVertex2fv(point) glEnd() display.flip()