def handle_click(self, event): """Show the load file dialog""" if self.load_dialog.ShowModal() == wx.ID_CANCEL: return pathname = self.load_dialog.GetPath() try: volume_io = VolumeIO(pathname) volume_data = volume_io.data volume = Volume(volume_data) TFUNC.init(volume.get_minimum(), volume.get_maximum()) self.file_name_label.SetLabel(f"File name: {basename(pathname)}") self.dimensions_label.SetLabel( f"Dimensions: {volume_io.dim_x}x{volume_io.dim_y}x{volume_io.dim_z}" ) self.value_range_label.SetLabel( f"Voxel value range: {volume.get_minimum():.3g}-{volume.get_maximum():.3g}" ) self.visualization.set_volume(volume) self.on_data_loaded(volume) except Exception: exc_type, exc_value, exc_traceback = sys.exc_info() traceback.print_exception(exc_type, exc_value, exc_traceback, limit=2, file=sys.stdout) dialog = wx.MessageDialog( None, message="An error occurred while reading the file", style=wx.ICON_ERROR | wx.OK) dialog.ShowModal() dialog.Destroy()
def render_slicer(self, view_matrix: np.ndarray, volume: Volume, image_size: int, image: np.ndarray): # Clear the image self.clear_image() # U vector. See documentation in parent's class u_vector = view_matrix[0:3] print("u_vector", u_vector) # V vector. See documentation in parent's class v_vector = view_matrix[4:7] print("v_vector", v_vector) # View vector. See documentation in parent's class view_vector = view_matrix[8:11] print("view_vector", view_vector) # Center of the image. Image is squared image_center = image_size / 2 print("image_size", image_size, "image_center", image_center) # Center of the volume (3-dimensional) volume_center = [volume.dim_x / 2, volume.dim_y / 2, volume.dim_z / 2] volume_maximum = volume.get_maximum() print("volume center", volume_center, ", volume_maximum", volume_maximum) # Define a step size to make the loop faster step = 2 if self.interactive_mode else 1 for i in range(0, image_size, step): for j in range(0, image_size, step): # Get the voxel coordinate X voxel_coordinate_x = u_vector[0] * (i - image_center) + v_vector[0] * (j - image_center) + \ volume_center[0] # Get the voxel coordinate Y voxel_coordinate_y = u_vector[1] * (i - image_center) + v_vector[1] * (j - image_center) + \ volume_center[1] # Get the voxel coordinate Z voxel_coordinate_z = u_vector[2] * (i - image_center) + v_vector[2] * (j - image_center) + \ volume_center[2] # Get voxel value value = get_voxel(volume, voxel_coordinate_x, voxel_coordinate_y, voxel_coordinate_z) # Normalize value to be between 0 and 1 red = value / volume_maximum green = red blue = red alpha = 1.0 if red > 0 else 0.0 # Compute the color value (0...255) red = math.floor(red * 255) if red < 255 else 255 green = math.floor(green * 255) if green < 255 else 255 blue = math.floor(blue * 255) if blue < 255 else 255 alpha = math.floor(alpha * 255) if alpha < 255 else 255 # Assign color to the pixel i, j image[(j * image_size + i) * 4] = red image[(j * image_size + i) * 4 + 1] = green image[(j * image_size + i) * 4 + 2] = blue image[(j * image_size + i) * 4 + 3] = alpha
def render_compositing(self, view_matrix: np.ndarray, volume: Volume, image_size: int, image: np.ndarray, step=1): # Clear the image self.clear_image() u_vector = view_matrix[0:3].reshape(-1, 1) v_vector = view_matrix[4:7].reshape(-1, 1) view_vector = view_matrix[8:11].reshape(-1, 1) image_center = image_size / 2 volume_center = np.asarray( [volume.dim_x / 2, volume.dim_y / 2, volume.dim_z / 2]).reshape(-1, 1) volume_maximum = volume.get_maximum() step = 10 if self.interactive_mode else 1 diagonal = np.sqrt(3) * np.max( [volume.dim_x, volume.dim_y, volume.dim_z]) / 2 diagonal = int(math.floor(diagonal)) + 1 for i in range(0, int(image_size), step): for j in range(0, int(image_size), step): red, green, blue, alpha = [0, 0, 0, 1] initial_color = TFColor(0, 0, 0, 0) for k in range(diagonal, -diagonal, -1): # Compute the new coordinates in a vectorized form voxel_cords = np.dot(u_vector, i - image_center) \ + np.dot(v_vector, j - image_center) \ + np.dot(view_vector, k) + volume_center voxel = get_voxelInterpolated(volume, voxel_cords[0], voxel_cords[1], voxel_cords[2]) color = self.tfunc.get_color(voxel) current_color = TFColor( color.a * color.r + (1 - color.a) * initial_color.r, color.a * color.g + (1 - color.a) * initial_color.g, color.a * color.b + (1 - color.a) * initial_color.b, color.a) initial_color = current_color red = math.floor(current_color.r * 255) if red < 255 else 255 green = math.floor(current_color.g * 255) if green < 255 else 255 blue = math.floor(current_color.b * 255) if blue < 255 else 255 alpha = math.floor(255) if alpha < 255 else 255 # Assign color to the pixel i, j image[(j * image_size + i) * 4] = red image[(j * image_size + i) * 4 + 1] = green image[(j * image_size + i) * 4 + 2] = blue image[(j * image_size + i) * 4 + 3] = alpha
def render_mip(self, view_matrix: np.ndarray, volume: Volume, image_size: int, image: np.ndarray): # Clear the image self.clear_image() # U vector. See documentation in parent's class u_vector = view_matrix[0:3].reshape(-1, 1) # V vector. See documentation in parent's class v_vector = view_matrix[4:7].reshape(-1, 1) # View vector. See documentation in parent's class view_vector = view_matrix[8:11].reshape(-1, 1) # Center of the image. Image is squared image_center = image_size / 2 # Center of the volume (3-dimensional) volume_center = np.asarray( [volume.dim_x / 2, volume.dim_y / 2, volume.dim_z / 2]).reshape(-1, 1) volume_maximum = volume.get_maximum() # Define a step size to make the loop faster step = 10 if self.interactive_mode else 1 diagonal = (np.sqrt(3) * np.max([volume.dim_x, volume.dim_y, volume.dim_z])) / 2 diagonal = int(math.floor(diagonal) + 1) for i in range(0, image_size, step): for j in range(0, image_size, step): max_voxel_value = [] for k in range(-diagonal, diagonal, 1): # Compute the new coordinates in a vectorized form voxel_cords = np.dot(u_vector, i-image_center) + np.dot(v_vector, j-image_center) \ + np.dot(view_vector, k) + volume_center max_voxel_value.append( get_voxelInterpolated(volume, voxel_cords[0], voxel_cords[1], voxel_cords[2])) value = np.amax(max_voxel_value) # Normalize value to be between 0 and 1 red = value / volume_maximum green = red blue = red alpha = 1.0 if red > 0 else 0.0 # Compute the color value (0...255) red = math.floor(red * 255) if red < 255 else 255 green = math.floor(green * 255) if green < 255 else 255 blue = math.floor(blue * 255) if blue < 255 else 255 alpha = math.floor(alpha * 255) if alpha < 255 else 255 # Assign color to the pixel i, j image[(j * image_size + i) * 4] = red image[(j * image_size + i) * 4 + 1] = green image[(j * image_size + i) * 4 + 2] = blue image[(j * image_size + i) * 4 + 3] = alpha
def render_slicer(self, view_matrix: np.ndarray, volume: Volume, image_size: int, image: np.ndarray): # Clear the image self.clear_image() # U vector. See documentation in parent's class u_vector = view_matrix[0:3] # V vector. See documentation in parent's class v_vector = view_matrix[4:7] # View vector. See documentation in parent's class view_vector = view_matrix[8:11] # Center of the image. Image is squared image_center = image_size / 2 # Center of the volume (3-dimensional) volume_center = [volume.dim_x / 2, volume.dim_y / 2, volume.dim_z / 2] volume_maximum = volume.get_maximum() # Define a step size to make the loop faster step = 2 if self.interactive_mode else 1 for i in range(0, image_size, step): for j in range(0, image_size, step): # Compute the new coordinates in a vectorized form voxel_cords = np.dot(u_vector, i - image_center) + np.dot( v_vector, j - image_center) + volume_center # Get voxel value value = get_voxel(volume, voxel_cords[0], voxel_cords[1], voxel_cords[2]) # Normalize value to be between 0 and 1 red = value / volume_maximum green = red blue = red alpha = 1.0 if red > 0 else 0.0 # Compute the color value (0...255) red = math.floor(red * 255) if red < 255 else 255 green = math.floor(green * 255) if green < 255 else 255 blue = math.floor(blue * 255) if blue < 255 else 255 alpha = math.floor(alpha * 255) if alpha < 255 else 255 # Assign color to the pixel i, j image[(j * image_size + i) * 4] = red image[(j * image_size + i) * 4 + 1] = green image[(j * image_size + i) * 4 + 2] = blue image[(j * image_size + i) * 4 + 3] = alpha
def render_mip(self, view_matrix: np.ndarray, volume: Volume, image_size: int, image: np.ndarray): self.clear_image() u_vector = view_matrix[0:3] v_vector = view_matrix[4:7] view_vector = view_matrix[8:11] image_center = image_size / 2 img_neg = (-1) * image_center volume_center = [volume.dim_x / 2, volume.dim_y / 2, volume.dim_z / 2] volume_maximum = volume.get_maximum() for i in range(0, image_size, 1): for j in range(0, image_size, 1): m = 0 for k in range(int(img_neg), int(image_center), 10): voxel_x = u_vector[0] * (i - image_center) + v_vector[0] * (j - image_center) + \ volume_center[0]+view_vector[0]*k voxel_y = u_vector[1] * (i - image_center) + v_vector[1] * (j - image_center) + \ volume_center[1] + view_vector[1] * k voxel_z = u_vector[2] * (i - image_center) + v_vector[2] * (j - image_center) + \ volume_center[2] + view_vector[2] * k tot_vox = mip_get_voxel(volume, voxel_x, voxel_y, voxel_z) if (tot_vox > m): m = tot_vox red = m / volume_maximum green = red blue = red alpha = 1.0 if red > 0 else 0.0 # Compute the color value (0...255) red = math.floor(red * 255) if red < 255 else 255 green = math.floor(green * 255) if green < 255 else 255 blue = math.floor(blue * 255) if blue < 255 else 255 alpha = math.floor(alpha * 255) if alpha < 255 else 255 # Assign color to the pixel i, j image[(j * image_size + i) * 4] = red image[(j * image_size + i) * 4 + 1] = green image[(j * image_size + i) * 4 + 2] = blue image[(j * image_size + i) * 4 + 3] = alpha
def render_mip(self, view_matrix: np.ndarray, volume: Volume, image_size: int, image: np.ndarray): # Clear the image self.clear_image() # ration vectors u_vector = view_matrix[0:3] # X v_vector = view_matrix[4:7] # Y view_vector = view_matrix[8:11] # Z # Center of the image. Image is squared image_center = image_size / 2 # Center of the volume (3-dimensional) volume_center = [volume.dim_x / 2, volume.dim_y / 2, volume.dim_z / 2] volume_maximum = volume.get_maximum() # Diagonal cube half_diagonal = math.floor( math.sqrt(volume.dim_x**2 + volume.dim_y**2 + volume.dim_z**2) / 2) # Define a step size to make the loop faster step = 20 if self.interactive_mode else 1 for i in tqdm(range(0, image_size, step), desc='render', leave=False): for j in range(0, image_size, step): value = 0 for k in range(-half_diagonal, half_diagonal, 3): # Get the voxel coordinates x = u_vector[0] * (i - image_center) + v_vector[0] * ( j - image_center) + view_vector[0] * k + volume_center[0] y = u_vector[1] * (i - image_center) + v_vector[1] * ( j - image_center) + view_vector[1] * k + volume_center[1] z = u_vector[2] * (i - image_center) + v_vector[2] * ( j - image_center) + view_vector[2] * k + volume_center[2] # Get voxel value tmp = get_voxel(volume, x, y, z) value = tmp if value < tmp else value # Normalize value to be between 0 and 1 red = value / volume_maximum green = red blue = red alpha = 1.0 if red > 0 else 0.0 # Compute the color value (0...255) red = math.floor(red * 255) if red < 255 else 255 green = math.floor(green * 255) if green < 255 else 255 blue = math.floor(blue * 255) if blue < 255 else 255 alpha = math.floor(alpha * 255) if alpha < 255 else 255 # Assign color to the pixel i, j image[(j * image_size + i) * 4] = red image[(j * image_size + i) * 4 + 1] = green image[(j * image_size + i) * 4 + 2] = blue image[(j * image_size + i) * 4 + 3] = alpha