def import_dicom_directory(parent = None, dtype = numpy.single, recursive=False, load_all_images=False): """ Import an image from a directory containing DICOM files parent : parent wx Window for dialogs dtype : type to cast images to, or None to preserve original type recursive : set to True to recursively search for DICOM files load_all_images : load all images contained in a file or just the first one """ preferences = medipy.gui.base.Preferences( wx.GetApp().GetAppName(), wx.GetApp().GetVendorName()) path = preferences.get("IO/load_path", "") dialog = wx.DirDialog(parent, defaultPath=path, style=wx.FD_OPEN) if dialog.ShowModal() != wx.ID_OK : return [] files = [] if recursive : for dirpath, dirnames, filenames in os.walk(dialog.GetPath()) : files.extend(os.path.join(dirpath, x) for x in filenames) else : files = [x for x in glob.glob(os.path.join(dialog.GetPath(), "*")) if os.path.isfile(x)] def loader(files) : datasets = [] for file in files : if medipy.io.dicom.can_read(str(file)) : datasets.append(medipy.io.dicom.read(str(file))) return datasets periodic_progress_dialog = PeriodicProgressDialog( 0.2, "Loading files", "Loading ...") worker_thread = WorkerThread(periodic_progress_dialog, target=loader, args=(files,)) worker_thread.start() periodic_progress_dialog.start() worker_thread.join() periodic_progress_dialog.Destroy() images = reconstruction.images(worker_thread.result, parent, dtype) if images : preferences.set("IO/load_path", dialog.GetPath()) return images else : return []
def get_dl(self,connection,dummy): """ Get SCU call, download selected objects Return a list of DataSets """ periodic_progress_dialog = PeriodicProgressDialog(0.2, "Get Retrieve", "Retrieving Data From Server ...") get_query = self.GetSelectedUids() results=[] for query in get_query: query_level = self.GetQueryLevel(query) get = medipy.network.dicom.scu.Get(connection, "patient", query_level, query) worker_thread = WorkerThread(periodic_progress_dialog,target=get) worker_thread.start() periodic_progress_dialog.start() worker_thread.join() results.extend(worker_thread.result) periodic_progress_dialog.Destroy() return results
def move_dl(self,connection,destination): """ Move SCU call to send selected objects to specified desination Return a list of DataSets """ periodic_progress_dialog = PeriodicProgressDialog(0.2, "Move Retrieve", "Retrieving Data From Server ...") move_query = self.GetSelectedUids() results = [] for query in move_query: query_level = self.GetQueryLevel(query) move = medipy.network.dicom.scu.Move(connection, "patient", query_level, destination, query) worker_thread = WorkerThread(periodic_progress_dialog,target=move) worker_thread.start() periodic_progress_dialog.start() worker_thread.join() results.extend(worker_thread.result) periodic_progress_dialog.Destroy() return results
def save(image, parent=None): """ Save an image with appropriate dialogs (file selector) Return the chosen save path or None parent : parent wx Window for dialogs """ dialog = ImageFileDialog(parent, style=wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) if dialog.ShowModal() != wx.ID_OK : return None path = dialog.GetPath() if isinstance(image, list) : periodic_progress_dialog = PeriodicProgressDialog(0.2, "Saving files", "Saving ...") worker_thread = WorkerThread(periodic_progress_dialog,target=medipy.io.save_serie, args=(image,path,)) worker_thread.start() periodic_progress_dialog.start() worker_thread.join() periodic_progress_dialog.Destroy() else : try : medipy.io.save(image, path) return path except : # Try by adding a ".nii" suffix try : path += ".nii" medipy.io.save(image, path) return path except : exc_info = sys.exc_info() logging.error("".join(traceback.format_exception(*exc_info))) wx.MessageBox("Could not save image to %s: %s"%(path, exc_info[1]), "Could not save image", wx.OK|wx.ICON_ERROR)
def __call__(self): # Save the current value of the parameters # self._save_parameters() # Build the expression namespace namespace = {"function": self._function} for parameter in self._parameters: if parameter.get("role", "") == "return": namespace[parameter["name"]] = None elif parameter.get("role", "") == "output": # Special case for images and 3D viewers if parameter["type"] == "Image" and self._controls[ parameter["name"]].output_checked: dummy = Image(shape=(1, 1, 1), value=0, dtype=numpy.single) namespace[parameter["name"]] = dummy elif parameter["type"] == "Object3D": dummy = Object3D(name="New object") namespace[parameter["name"]] = dummy else: namespace[parameter["name"]] = self._controls[ parameter["name"]].value else: # Parameter will not be modified namespace[parameter["name"]] = self._controls[ parameter["name"]].value # Build the expression args = [] return_values = [] for parameter in self._parameters: if parameter.get("role", "") == "return": return_values.append(parameter["name"]) else: args.append("{0} = {0}".format(parameter["name"])) expression = "function({0})".format(", ".join(args)) if return_values: return_expression = ", ".join(return_values) expression = "{0} = {1}".format(return_expression, expression) # Execute it def f(): exec expression in namespace periodic_progress_dialog = PeriodicProgressDialog( 0.2, "Running %s ..." % self._function.func_name, "Running %s ..." % self._function.func_name) worker_thread = WorkerThread(periodic_progress_dialog, target=f) worker_thread.start() periodic_progress_dialog.start() worker_thread.join() periodic_progress_dialog.Destroy() if worker_thread.exception: wx.MessageBox( "Could not run function : {0}".format(worker_thread.exception), "Could not run function") else: # Update controls and application for parameter in self._parameters: if parameter.get("role", "") not in ["return", "output"]: # Parameter has not been modified continue else: name = parameter["name"] value = namespace[name] control = self._controls[name] # Special case for Image and Object3D if parameter["type"] == "Image": if control.output_checked: self.notify_observers("new_image", image=value) else: self.notify_observers("replace_image", old=control.value, new=value) elif parameter["type"] == "Object3D": if control.output_checked: viewer = Viewer3DFrame(parent=None, objects_3d=ObservableList()) viewer.Show() self.notify_observers("new_viewer_3d", viewer=viewer) control.value = self._viewer_3ds[-1] viewer_3d = control.value viewer_3d.objects_3d.append(value) # If object has an associated image, set the GUI image image = value.image if image is not None: self.notify_observers("set_image_to_object_3d", image=image, object_3d=value) if len(viewer_3d.objects_3d) == 1: viewer_3d.view_all() viewer_3d.update_object_editor() # In any case but Object3D (whose value is a Viewer3D), # update the control if parameter["type"] != "Object3D": control.value = value
def load(parent=None, dtype=numpy.single, multiple=False, wildcard="*"): """ Load images with appropriate dialogs (file selector, and DICOM selector if needed). parent : parent wx Window for dialogs dtype : type to cast images to, or None to preserve original type multiple : allow selection of several images wildcard : dialog wildcard Return a list of loaded images """ style = (wx.FD_OPEN | wx.FD_MULTIPLE) if multiple else wx.FD_OPEN dialog = ImageFileDialog(parent, style=style) dialog.SetWildcard(wildcard) if dialog.ShowModal() != wx.ID_OK : return [] paths = dialog.GetPaths() if multiple else [dialog.GetPath()] images = [] dicomdirs, non_dicomdirs = _separate_dicomdirs(paths) # Load all dicomdirs for path in dicomdirs : periodic_progress_dialog = PeriodicProgressDialog( 0.2, "Loading DICOMDIR", "Loading ...") worker_thread = WorkerThread(periodic_progress_dialog, target=medipy.io.dicom.read, args=(path,)) worker_thread.start() periodic_progress_dialog.start() worker_thread.join() periodic_progress_dialog.Destroy() if worker_thread.exception is not None : wx.MessageBox("Could not load file {0} : {1}".format( path, worker_thread.exception), "Could not load DICOMDIR") else : new_images = reconstruction.images( [worker_thread.result], parent, dtype) if new_images: images.append(new_images) # Load other images periodic_progress_dialog = PeriodicProgressDialog(0.2, "Loading image", "Loading ...") for path in non_dicomdirs : periodic_progress_dialog.Pulse("Loading {0}...".format(path)) periodic_progress_dialog.Fit() worker_thread = WorkerThread(periodic_progress_dialog, target=medipy.io.load, args=(path, dtype)) worker_thread.start() periodic_progress_dialog.start() worker_thread.join() if worker_thread.exception is not None : wx.MessageBox("Could not load file {0} : {1}".format( path, worker_thread.exception), "Could not load image") else : if worker_thread.result: images.append(worker_thread.result) periodic_progress_dialog.Destroy() return images
def images(datasets, parent, dtype=numpy.single, size=(700, 700), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER): """ Return a list of medipy.base.Image objects from a list of DataSets. """ dialog = ExplorerDialog(parent, size=size, style=style) dialog.set_datasets(datasets) # Size must be specified explicitely on Windows dialog.SetSize((700, 700)) if dialog.ShowModal() != wx.ID_OK: dialog.Destroy() return [] dialog.Destroy() # Get selected series from dialog, load it. series = dialog.get_selected_datasets() periodic_progress_dialog = PeriodicProgressDialog(0.2, "Loading files", "Loading files ...") worker_thread = WorkerThread(periodic_progress_dialog, target=medipy.io.dicom.load_dicomdir_records, args=(series, )) worker_thread.start() periodic_progress_dialog.start() worker_thread.join() periodic_progress_dialog.Destroy() if worker_thread.exception is not None: wx.MessageBox( "Could not load series : %s" % (worker_thread.exception, ), "Could not load series") return [] series = worker_thread.result # Reconstruct one image per stack series = medipy.io.dicom.split.images(series) series = medipy.io.dicom.normalize.normalize(series) stacks = medipy.io.dicom.stacks(series) result = [] periodic_progress_dialog = PeriodicProgressDialog( 0.2, "Reconstructing images", "Reconstructing images (%i/%i) ..." % (0, len(stacks))) for index, stack in enumerate(stacks): periodic_progress_dialog.Pulse("Reconstructing images (%i/%i) ..." % (index + 1, len(stacks))) worker_thread = WorkerThread(periodic_progress_dialog, target=medipy.io.dicom.image, args=(stack, )) worker_thread.start() periodic_progress_dialog.start() worker_thread.join() if worker_thread.exception is not None: wx.MessageBox( "Could not reconstruct image : %s" % (worker_thread.exception, ), "Could not reconstruct image") else: image = worker_thread.result if dtype is not None: image.data = image.data.astype(dtype) result.append(image) periodic_progress_dialog.Destroy() return result