def __init__(self, num_img, num_tth, levels): self.num_image = num_img self.num_tooth = num_tth self.pathLandmarks = "Project_Data/_Data/Landmarks/original/landmarks" + str( num_img) + "-" + str(num_tth) + ".txt" # self.pathLandmarks = "Project Data/_Data/Landmarks/mirrored/landmarks" + str(num_img+14) + "-" + str( # num_tth) + ".txt" points = np.loadtxt(self.pathLandmarks) landmarks = np.zeros((2, 40)) landmarks[0, :] = points[::2] landmarks[1, :] = points[1::2] landmarks = np.roll(landmarks, 5, axis=1) self.path_radiograph = "Project_Data/_Data/Radiographs_Preprocessed/" + str( num_img).zfill(2) + ".tif" # self.path_radiograph = "Project_Data/_Data/Radiographs/" + str(num_img).zfill(2) + ".tif" # self.path_radiograph = "Project_Data/_Data/Segmentations_Preprocessed/" + str(num_img).zfill(2) + ".tif" img_radiograph = cv2.imread(self.path_radiograph, 0) self.path_segmentation = "Project_Data/_Data/Segmentations/" + str( num_img).zfill(2) + "-" + str(num_tth - 1) + ".png" img_segmentation = cv2.imread(self.path_segmentation, 0) ObjectShape.__init__(self, landmarks, img_radiograph, k=3, levels=levels) del points del landmarks
def reconstruct_shape_object(shape_mu, P, b): """ x = mu + P*b """ lm_x = shape_mu.lm_loc + np.dot(P, b).reshape(shape_mu.lm_org.shape) lm_x = lm_x * shape_mu.scale + shape_mu.center return ObjectShape(lm_x)
def match_model_to_target(self): b = self.b * 0 b_old = np.copy(b) max_iter = 3 num_iter = 0 while True: b = project_shape_to_principal_components_space(self.shape_target, self.shape_ref, self.eigenvectors) limit = 2 for idx, param in enumerate(b): if b[idx] > limit * np.sqrt(self.eigenvalues[idx]): b[idx] = limit * np.sqrt(self.eigenvalues[idx]) elif b[idx] < -limit * np.sqrt(self.eigenvalues[idx]): b[idx] = -limit * np.sqrt(self.eigenvalues[idx]) shape_new_model = reconstruct_shape_object(self.shape_ref, self.eigenvectors, b) theta = shape_new_model.get_landmarks_theta(self.shape_target.lm_loc) lm_model = np.dot(myLib.getRotMatrix(theta), shape_new_model.lm_loc) lm_model = lm_model * self.shape_target.scale + self.shape_target.center self.shape_model = ObjectShape(lm_model, self.img, k=8, levels=self.current_level + 1) procrustes_alignment([self.shape_model], self.shape_target) lm_new = self.shape_model.lm_loc * self.shape_target.scale + self.shape_target.center self.shape_model = ObjectShape(lm_new, self.img, k=8, levels=self.current_level + 1) b_change = b - b_old b_old = np.copy(b) if np.sum(b_change) < 1e-10: break num_iter += 1 if num_iter > max_iter: break
def __init__(self, shapes_list, img, init_pos, levels, visualization='True'): self.init_center = np.copy(init_pos) self.img = np.copy(img) self.shape_ref = procrustes_analysis(shapes_list, visualization=False) eigenval, eigenvec, lm_mu = principal_component_analysis(shapes_list, self.shape_ref, 5) self.eigenvalues = eigenval self.eigenvectors = eigenvec self.profile_intensity_mean = get_profile_intensity_mean(shapes_list) self.current_level = levels - 1 # lm_model = (self.shape_ref.lm_org - self.shape_ref.center + self.init_center).astype(np.int) lm_model = (self.shape_ref.lm_org - self.shape_ref.center) / 1.30 lm_model = (lm_model + self.init_center).astype(np.int) self.shape_model = ObjectShape(lm_model, self.img, k=5, levels=self.current_level + 1) self.shape_target = None self.b = np.zeros_like(self.eigenvalues) self.visualization = visualization if self.visualization: self.fig = plt.figure() myLib.move_figure('right') plt.imshow(self.shape_model.img, cmap='gray', interpolation='bicubic') plt.plot(self.init_center[0, 0], self.init_center[1, 0], color='r', marker='.', markersize=5) self.update_figure() message = 'Initial estimation shown. Press key to start the search...' # message = "" self.pause_and_show_figure_message(message) # self.update_target_points() # self.update_figure() # plt.waitforbuttonpress() # # self.match_model_to_target() # self.update_figure() # plt.waitforbuttonpress() # plt.waitforbuttonpress() # self.active_shape_model_algorithm() self.multi_resolution_search()
def update_target_points(self): lm_target = np.zeros_like(self.shape_model.lm_org) len_k = np.size(self.profile_intensity_mean, axis=1) len_ns = np.size(self.shape_model.profile_intensity, axis=1) for idx_lm in range(np.size(self.shape_model.lm_org, axis=1)): intensity_match = np.zeros((len_ns - len_k + 1,)) intensity_similarity = np.zeros((len_ns - len_k + 1,)) for idx_k in range(len_ns - len_k + 1): model_intensity = self.shape_model.profile_intensity[idx_lm, idx_k:idx_k + len_k, self.current_level] mean_intensity = self.profile_intensity_mean[idx_lm, :, self.current_level] intensity_error = (model_intensity - mean_intensity) intensity_error = intensity_error ** 2 intensity_match[idx_k] = np.sum(intensity_error) inner_product = model_intensity * mean_intensity intensity_similarity[idx_k] = np.sum(inner_product) # if (idx_lm > 0) and (idx_lm < 2): # plt.figure() # plt.title('shift = ' + str(idx_k)) # plt.plot(model_intensity, 'b-') # plt.plot(mean_intensity, 'r-') # plt.show() # plt.waitforbuttonpress() # # plt.close() # idx_min_error = np.argmin(intensity_match) idx_min_error = np.argmax(intensity_similarity) idx_best_match = idx_min_error + (len_k - 1) / 2 lm_target[:, idx_lm] = self.shape_model.profile_coordinates[:, idx_lm, idx_best_match, self.current_level] # if (idx_lm > 0) and (idx_lm < 2): # and (self.current_level == 1): # # self.show_profile_intensity_match(idx_lm, intensity_match, idx_min_error) # self.show_profile_intensity_match(idx_lm, intensity_similarity, idx_min_error) self.shape_target = ObjectShape(lm_target * (2 ** self.current_level)) self.update_figure()
incisors_good_fit, incisors_bad_fit = separate_good_bad_shape_fit(incisors) # shape_viewer_good = ShapesViewer(incisors_good_fit, incisor_ref, "good shapes") # shape_viewer_good.update_shapes_ref() # shape_viewer_good.update_shapes_all() # # shape_viewer_bad = ShapesViewer(incisors_bad_fit, incisor_ref, "bad shapes") # shape_viewer_bad.update_shapes_ref() # shape_viewer_bad.update_shapes_all() # training_set = create_training_set(incisors_good_fit, incisor_ref) eigenval, eigenvec, lm_mu = principal_component_analysis(incisors_good_fit, incisor_ref, 3) print "\neigenvalues = " + str(eigenval) # print "\neigenvectors = " + str(eigenvec) incisor_mu = ObjectShape(lm_mu.reshape(2, np.size(lm_mu, 0) / 2)) # diff_mean = incisor_mu.lm_org - incisor_ref.lm_org # # print "\ndiff_mean:" # # print str(diff_mean) # # shape_viewer_mu = ShapesViewer([incisor_mu], incisor_ref) # shape_viewer_mu.update_shapes_ref() # shape_viewer_mu.update_shapes_all() show_modes(incisor_mu, eigenvec, eigenval) # Save PCA dir_path = "Project_Data/_Data/PCA/" # save_PCA_results(dir_path, "incisor", incisor_idx, eigenvec, eigenval, lm_mu) # plt.figure() print "\nClick to finish process..."
def procrustes_analysis(shapes_list, visualization=True): # Arbitrarily choose a reference shape (typically by selecting it among the available instances) # np.random.seed(3) # idx = np.random.randint(0, len(shapes_list)) idx = 9 # print "idx = " + str(idx) shape_ref = ObjectShape(shapes_list[idx].lm_org, shapes_list[idx].img) # print "r = " + str(shape_ref.num_image) # print "t = " + str(shape_ref.num_tooth) # shape_ref.show_radiograph(np.array([800, 200])) if visualization: shapes_viewer = ShapesViewer(shapes_list, shape_ref) shapes_viewer.update_shapes_ref() for shape_idx in range(len(shapes_list)): shapes_viewer.update_shape_idx(shape_idx) # shape_mean = ObjectShape(np.zeros_like(shape_ref.lm_loc)) iteration_max = 30 iteration_cnt = 0 while True: if visualization: shapes_viewer.update_shapes_all() # Superimpose all instances to current reference shape procrustes_alignment(shapes_list, shape_ref) if visualization: shapes_viewer.update_shapes_all() # Compute the mean shape of the current set of superimposed shapes lm_mean = np.zeros_like(shape_ref.lm_loc, dtype=float) for shape in shapes_list: lm_mean = lm_mean + shape.lm_loc * shape.scale lm_mean = lm_mean / float(len(shapes_list)) shape_mean = ObjectShape(lm_mean) # Compute square distance change of mean shape ssdc = np.sum(np.square(shape_ref.lm_org - lm_mean)) if visualization: print "sum of square distance change: " + str(ssdc) # Update reference shape shape_ref.lm_org = shape_mean.lm_org shape_ref.lm_loc = shape_mean.lm_loc shape_ref.center = shape_mean.center shape_ref.scale = shape_mean.scale shape_ref.theta = shape_mean.theta if visualization: shapes_viewer.update_shapes_ref() # End loop if sum of square distance change of mean shape is under certain threshold if ssdc < 1e-8: if visualization: print( "Procrustes analysis finished. Square distance change of mean shape was under certain threshold." ) break # End loop if number of iteration exceeds maximum number of allowed iterations if iteration_cnt >= iteration_max: if visualization: print( "Procrustes analysis finished. Number of iteration exceeded the maximum allowed iterations." ) break iteration_cnt = iteration_cnt + 1 # axis_len_0 = 2 # DOF # axis_len_1 = len(shapes_list) shape_centers_sum = np.zeros((2, 1)) # shape_theta_sum = 0 for idx_shape, shape in enumerate(shapes_list): shape.set_ssd(shape_ref.lm_loc) # print shape.ssd shape_centers_sum += shape.center # shape_theta_sum += shape.theta shape_centers = shape_centers_sum / len(shapes_list) # shape_theta = shape_theta_sum / len(shapes_list) # print "Avrage theta" + str(shape_theta) shape_ref.center = shape_centers shape_ref.lm_org += shape_ref.center return shape_ref