def __init__(self): """This Class contains the main window of the program""" super(ApplicationWindow, self).__init__() self.collection = [] self.loader = FileLoader() self._initUI()
class ApplicationWindow(QtGui.QMainWindow): def __init__(self): """This Class contains the main window of the program""" super(ApplicationWindow, self).__init__() self.collection = [] self.loader = FileLoader() self._initUI() def _initUI(self): """ Gui initicializater""" self.timer = QtCore.QTimer() # Timer intended to update the image self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.file_menu = QtGui.QMenu('File', self) self.file_menu.addAction('Choose path', self.open_path, QtCore.Qt.CTRL + QtCore.Qt.Key_O) self.file_menu.addAction('Exit', self.fileQuit, QtCore.Qt.CTRL + QtCore.Qt.Key_Q) self.menuBar().addMenu(self.file_menu) self.animation_menu = QtGui.QMenu('Animation', self) self.action_animation_start = self.animation_menu.addAction('&Start', self.start_animation, QtCore.Qt.Key_S) self.action_animation_pause = self.animation_menu.addAction('Pause/Resume', self.pause_animation, QtCore.Qt.Key_Space) self.paused = False # flag to control pause animation self.menuBar().addMenu(self.animation_menu) self.sample_menu = QtGui.QMenu('Sample', self) self.action_sample_segment = self.sample_menu.addAction('Segment sample', self.segment_sample, QtCore.Qt.CTRL + QtCore.Qt.Key_S) self.action_sample_3d = self.sample_menu.addAction('Show 3D model', self.show_3d_sample) self.action_sample_count = self.sample_menu.addAction('Count segmented elements', self.count_element_values) self.menuBar().addMenu(self.sample_menu) self.simulation_menu = QtGui.QMenu('Simulation', self) self.simulation_setup = self.simulation_menu.addAction('Set up simulation...', self.setup_simulation) self.menuBar().addMenu(self.simulation_menu) self.help_menu = QtGui.QMenu('Help', self) self.menuBar().addSeparator() self.menuBar().addMenu(self.help_menu) self.help_menu.addAction('Help', self.help_dialog) self.help_menu.addAction('About...', self.about) open_button = QtGui.QPushButton('Choose work path', self) open_button.clicked[bool].connect(self.open_path) # Button listener self.main_widget = QtGui.QWidget(self) l = QtGui.QGridLayout(self.main_widget) self.dc = MyDynamicMplCanvas(self.main_widget, width=5, height=4, dpi=100) self.folder_path = QtGui.QLineEdit(self) self.folder_path.setReadOnly(True) # The only way to edit path should be by using the button l.addWidget(self.folder_path, 1, 1) l.addWidget(open_button, 1, 2) l.addWidget(self.dc, 2, 1, 2, 2) self.setGeometry(10, 35, 560, 520) window_size = self.geometry() left = window_size.left() right = window_size.right() - 500 top = window_size.top() + 200 bottom = window_size.bottom() - 20 self.window_size = QtCore.QRect(left, top, bottom, right) self.main_widget.setFocus() self.setCentralWidget(self.main_widget) self.menu_buttons_state() def open_path(self): """ Shows an "open folder dialog" looking for Dicom files to load """ self.pause_animation(); self.update_staus("Loading files from path...") current_path = os.path.dirname(os.path.abspath(__file__)) + '/samples/4/' chosen_path = QtGui.QFileDialog.getExistingDirectory(None, 'Open working directory', current_path, QtGui.QFileDialog.ShowDirsOnly) path = str(chosen_path + "/") # QString to Python string # Prevents the execution of load_path if the user don't select a folder try: self.collection = self.loader.load_path(path) # Load Files print type(self.collection[0]), self.collection[0].shape except Exception as msg_error: print "Error loading the image files", msg_error QtGui.QMessageBox.information(self, "Error", str(msg_error)) else: total_loaded = str(len(self.collection)) + " files loaded." self.folder_path.setText(path) self.update_staus(total_loaded) self.menu_buttons_state(True) QtGui.QMessageBox.about(self, "Information:", total_loaded) def start_animation(self): """ Run the 2D animation of the X-Ray raw or treated Dicom slices from the asphalt mixture sample """ self.dc.reset_index() QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.dc.update_figure) self.timer.start(150) # Set the update time self.paused = False def pause_animation(self): """ Pause and Resume the 2D animation of the X-Ray raw or treated Dicom slices from the asphalt mixture sample """ if self.paused: self.timer.start(150) self.paused = False else: self.timer.stop() self.paused = True def update_staus(self, message): """ Set text over the status bar on the main window of the application """ self.statusBar().showMessage(message) def segment_sample(self): """ Thorugh a controller it reduces and segmentes the toymodel. This also enables the application window to show the animation of the treated sample """ self.progressBar = QtGui.QProgressBar(self) # self.progressBar.setGeometry(QtCore.QRect(50, 210, 460, 40)) self.progressBar.setGeometry(self.window_size) controller = SegmentationController(self.collection) self.update_staus("Segmenting and reducing the sample...") def onFinished(): self.progressBar.setRange(0, 1) self.progressBar.setValue(1) self.collection = controller.getData() self.update_staus("Segmenting and reducing completed...") self.dc.reset_index() self.action_sample_3d.setEnabled(True) # Enables the 3D Model viewer self.action_sample_count.setEnabled(True) # Enables the count method self.simulation_setup.setEnabled(True) # Enables the simulation setup self.action_sample_segment.setEnabled(False) # Disables de segmentation action self.progressBar.close() self.count_element_values() controller.finished.connect(onFinished) controller.start() self.progressBar.show() self.progressBar.setRange(0, 0) def show_3d_sample(self): """ Load the 3D render script """ try: from output.render_3d import ToyModel3d print "Running 3D Modeling..." self.update_staus("Running 3D Modeling...") ToyModel3d(self.collection) except: print "Please check Mayavi installation" QtGui.QMessageBox.information(self, "Error", "Please check your Mayavi installation") def count_element_values(self): """Shows the total count of detected elements after the segmentation""" from numpy import count_nonzero from imgprocessing.slice_mask import apply_mask collection_mask = self.collection.copy() collection_mask = apply_mask(collection_mask) empty = count_nonzero(collection_mask == 0) mastic = count_nonzero(collection_mask == 1) aggregate = count_nonzero(collection_mask == 2) total = (empty + mastic + aggregate) QtGui.QMessageBox.about(self, "Element counting", """ <br> <table> <tr><th>The sample has = %s pixels:</th><\tr> <tr> <td>Empty pixels = %s</td> <td>%3.2f%%</td> </tr> <tr> <td>Mastic pixels = %s</td> <td>%3.2f%%</td> </tr> <tr> <td>Aggregate pixels = %s</td> <td>%3.2f%%</td> </tr> </table> """ % (total, empty, ((empty * 100.) / total), mastic, ((mastic * 100.) / total), aggregate, \ ((aggregate * 100.) / total))) def menu_buttons_state(self, state=False): """Enable/Disable menu options except the Count element option the count method requires samples to be segmented""" self.action_sample_count.setEnabled(False) self.action_sample_3d.setEnabled(False) self.simulation_setup.setEnabled(False) self.action_animation_pause.setEnabled(state) # self.action_animation_resume.setEnabled(state) self.action_animation_start.setEnabled(state) self.action_sample_segment.setEnabled(state) def fileQuit(self): """ Pause the animation on the main window and destroy the canvas objects in order to close the application witout errors """ self.pause_animation() self.dc.destroy() self.close() def closeEvent(self, ce): """ Handle the window close event""" self.fileQuit() def about(self): """Shows the about dialog""" QtGui.QMessageBox.about(self, ("%s") % "About", \ """ <br><b>Asphalt Mixtures Aging Simulator</b> <p>Copyright © 2014-2015 Jeison Pacateque, Santiago Puerto, Wilmar Fernandez <br>Licensed under the terms of the GNU GPLv3 License <p>Created by Jeison Pacateque, Santiago Puerto and Wilmar Fernandez <p>This project performs a 3D reconstruction of a cylindrical asphalt mixture sample from a set images on a Dicom file format. The components of asphalt mixture will be identified through 3-phase segmentation. Additionally, a 3D model of the asphalt mixture reconstruction was developed. The project was implemented on the Python programming language using the open-source libraries Numpy, Scipy, Pydicom, Scikit-learn, Matplotlib and Mayavi. A simulation of the asphalt mixtures aging process is implemented using numerical methods on the mechanical, themical and chemical fields. <p>The source is hosted on <a href="https://github.com/JeisonPacateque/Asphalt-Mixtures-Aging-Simulator"> Github</a> <p>Pavements and Sustainable Materials Research Group <br>Grupo de Investigación en Pavimentos y Materiales Sostenibles <br>Universidad Distrital Francisco José de Caldas """) def help_dialog(self): QtGui.QMessageBox.about(self, "Help", """<b>Asphalt Mixtures Aging Simulator</b> <p>You can find <a href="http://asphalt-mixtures-aging-simulator.readthedocs.org"> here </a> the complete documentation of the project. <p>Pavements and Sustainable Materials Research Group<br/> Universidad Distrital Francisco José de Caldas """) def get_collection(self): return self.collection def set_collection(self, collection): self.collection = collection def setup_simulation(self): """Shows the configure simulation dialog""" self.config_dialog = ConfigureSimulationDialog(self.collection) self.config_dialog.exec_() # Prevents the dialog to disappear
print "Segmentation finished with", str(col_length), "samples in", \ str(end_time - start_time), "seconds." return segmented #---------------------------------------------------------------------------------- if __name__ == '__main__': import sys, os sys.path.insert(0, os.path.abspath('../')) from integration.file_loader import FileLoader loader = FileLoader() file_path = os.path.dirname('../')+'/samples/4/sample_20.dcm' segmentation = Segmentation() img_org = loader.single_dicom_read(file_path) img_temporal = img_org.copy() # Copy of the image to process img_seg = segmentation.clasify(img_org) # Segment original image # Reduce img_temporal (avoid manipulation of the variable) img_red = segmentation.reduction(img_temporal) red_seg = segmentation.clasify(img_red) # Segment reduced image segmentation.view(img_org, img_seg, red_seg) # Show results