labeling_tool.py
Go to the documentation of this file.
00001 #!/usr/bin/python
00002 #
00003 # Copyright (c) 2010, Georgia Tech Research Corporation
00004 # All rights reserved.
00005 #
00006 # Redistribution and use in source and binary forms, with or without
00007 # modification, are permitted provided that the following conditions are met:
00008 #     * Redistributions of source code must retain the above copyright
00009 #       notice, this list of conditions and the following disclaimer.
00010 #     * Redistributions in binary form must reproduce the above copyright
00011 #       notice, this list of conditions and the following disclaimer in the
00012 #       documentation and/or other materials provided with the distribution.
00013 #     * Neither the name of the Georgia Tech Research Corporation nor the
00014 #       names of its contributors may be used to endorse or promote products
00015 #       derived from this software without specific prior written permission.
00016 #
00017 # THIS SOFTWARE IS PROVIDED BY GEORGIA TECH RESEARCH CORPORATION ''AS IS'' AND
00018 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00019 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00020 # DISCLAIMED. IN NO EVENT SHALL GEORGIA TECH BE LIABLE FOR ANY DIRECT, INDIRECT,
00021 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023 # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
00025 # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00026 # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 #
00028 
00029 #  \author Martin Schuster (Healthcare Robotics Lab, Georgia Tech.)
00030 import roslib; roslib.load_manifest('laser_camera_segmentation')
00031 
00032 from opencv.highgui import cvLoadImage
00033 
00034 import sys
00035 import opencv.cv as cv
00036 import opencv.highgui as hg
00037 
00038 from PyQt4 import QtGui, QtCore
00039 
00040 import shutil #file operations
00041 import os
00042 
00043 
00044 from dumpObj import dumpObj
00045 
00046 from labeling import label_object, scan_dataset, scans_database
00047 
00048 
00049 #take scans:
00050 import laser_camera_segmentation.scanner as scanner 
00051 import laser_camera_segmentation.processor as processor
00052 import laser_camera_segmentation.configuration as configuration
00053 import hrl_lib.util as ut  
00054 
00055 
00056 class labeling_tool(QtGui.QWidget):
00057     
00058     draw_widget = None
00059     display_mode = 'image'
00060     
00061     display_3d_type = 'height'
00062     
00063     def __init__(self, path, parent=None):
00064         
00065         self.init_in_progress = True
00066         
00067         self.path = path
00068         
00069         # load configs for taking scans, etc:
00070         self.config = configuration.configuration(path)
00071         #create scanner and processor when needed:
00072         self.scanner = False
00073         self.processor = False
00074         
00075         # load database:
00076         self.scans_database = scans_database.scans_database()
00077         self.scans_database.load(path,'database.pkl')
00078         
00079         #get first dataset:
00080         self.current_dataset = self.scans_database.get_dataset(0)
00081 
00082         QtGui.QWidget.__init__(self, parent)
00083         self.setWindowTitle('labeling tool')
00084         
00085 
00086         left_layout = QtGui.QVBoxLayout()
00087         self.draw_widget = draw_widget(self.current_dataset.polygons, self.scans_database.get_path() + '/' + self.current_dataset.image_filename, self)
00088         
00089         title_layout = QtGui.QHBoxLayout()
00090         
00091         take_scan_button = QtGui.QPushButton('Scan')
00092         take_scan_button.setMaximumWidth(50)
00093         title_layout.addWidget(take_scan_button)
00094         self.connect(take_scan_button, QtCore.SIGNAL('clicked()'), self.slot_take_scan )      
00095         
00096         take_artag_image_button = QtGui.QPushButton('ARTag')
00097         take_artag_image_button.setMaximumWidth(50)
00098         title_layout.addWidget(take_artag_image_button)
00099         self.connect(take_artag_image_button, QtCore.SIGNAL('clicked()'), self.slot_take_artag_image )              
00100         
00101         button = QtGui.QPushButton('Import Img')
00102         title_layout.addWidget(button)
00103         self.connect(button, QtCore.SIGNAL('clicked()'), self.slot_import_image )                 
00104         
00105         label = QtGui.QLabel("View: ")
00106         title_layout.addWidget(label)
00107         self.display_3d_button = QtGui.QPushButton('3D')
00108         self.display_3d_button.setMaximumWidth(40)
00109         title_layout.addWidget(self.display_3d_button)
00110         self.connect(self.display_3d_button, QtCore.SIGNAL('clicked()'), self.slot_display_3d )
00111         
00112         combobox = QtGui.QComboBox()
00113         combobox.addItem("Height", QtCore.QVariant("height"))
00114         combobox.addItem("Intensities", QtCore.QVariant("intensities"))
00115         #combobox.addItem("objects", QtCore.QVariant("objects"))
00116         combobox.addItem("Labels", QtCore.QVariant("labels"))
00117         combobox.addItem("Classifier range", QtCore.QVariant("range"))
00118         combobox.addItem("Classifier color", QtCore.QVariant("color"))
00119         combobox.addItem("Classifier all", QtCore.QVariant("all"))
00120         combobox.addItem("Classifier all+post", QtCore.QVariant("all_post"))
00121         combobox.addItem("Baseline algo", QtCore.QVariant("baseline"))
00122         combobox.addItem("h", QtCore.QVariant("h"))
00123         combobox.addItem("s", QtCore.QVariant("s"))
00124         combobox.addItem("v", QtCore.QVariant("v"))
00125         self.connect(combobox, QtCore.SIGNAL('currentIndexChanged(int)'), self.slot_update_display_3d_type)  
00126         title_layout.addWidget(combobox)
00127         self.display_3d_type_combobox = combobox;        
00128         
00129         
00130         self.display_3d_spheres_button = QtGui.QPushButton('3D_Spheres')
00131         title_layout.addWidget(self.display_3d_spheres_button)
00132         self.connect(self.display_3d_spheres_button, QtCore.SIGNAL('clicked()'), self.slot_display_3d_spheres )                  
00133         self.display_intensity_button = QtGui.QPushButton('Intensity')
00134         self.display_intensity_button.setMaximumWidth(50)
00135         title_layout.addWidget(self.display_intensity_button)
00136         self.connect(self.display_intensity_button, QtCore.SIGNAL('clicked()'), self.slot_display_intensity )   
00137         self.display_features_button = QtGui.QPushButton('Features')
00138         title_layout.addWidget(self.display_features_button)
00139         self.display_features_button.setMaximumWidth(50)
00140         self.connect(self.display_features_button, QtCore.SIGNAL('clicked()'), self.slot_display_features )   
00141         self.display_labels_button = QtGui.QPushButton('Labels')
00142         title_layout.addWidget(self.display_labels_button)
00143         self.display_labels_button.setMaximumWidth(50)
00144         self.connect(self.display_labels_button, QtCore.SIGNAL('clicked()'), self.slot_display_labels )   
00145         self.display_stats_button = QtGui.QPushButton('Stats')
00146         title_layout.addWidget(self.display_stats_button)
00147         self.display_stats_button.setMaximumWidth(50)
00148         self.connect(self.display_stats_button, QtCore.SIGNAL('clicked()'), self.slot_display_stats )   
00149         self.display_global_stats_button = QtGui.QPushButton('Global Stats')
00150         title_layout.addWidget(self.display_global_stats_button)
00151         self.display_global_stats_button.setMaximumWidth(50)
00152         self.connect(self.display_global_stats_button, QtCore.SIGNAL('clicked()'), self.slot_display_global_stats )         
00153         
00154         self.line_edits = []
00155     
00156         self.add_line_edit('Title:',title_layout,'title')
00157 
00158 
00159         first_dataset_button = QtGui.QPushButton('<<')
00160         first_dataset_button.setMaximumWidth(30)
00161         title_layout.addWidget(first_dataset_button)
00162         self.connect(first_dataset_button, QtCore.SIGNAL('clicked()'), self.slot_first_dataset )
00163         prev_dataset_button = QtGui.QPushButton('<')
00164         prev_dataset_button.setMaximumWidth(30)
00165         title_layout.addWidget(prev_dataset_button)
00166         self.connect(prev_dataset_button, QtCore.SIGNAL('clicked()'), self.slot_prev_dataset )
00167         next_dataset_button = QtGui.QPushButton('>')
00168         next_dataset_button.setMaximumWidth(30)
00169         title_layout.addWidget(next_dataset_button)
00170         self.connect(next_dataset_button, QtCore.SIGNAL('clicked()'), self.slot_next_dataset )
00171         last_dataset_button = QtGui.QPushButton('>>')
00172         last_dataset_button.setMaximumWidth(30)
00173         title_layout.addWidget(last_dataset_button)
00174         self.connect(last_dataset_button, QtCore.SIGNAL('clicked()'), self.slot_last_dataset )        
00175         
00176         save_button = QtGui.QPushButton('Save')
00177         title_layout.addWidget(save_button)
00178         save_button.setMaximumWidth(50)
00179         self.connect(save_button, QtCore.SIGNAL('clicked()'), self.slot_save )
00180         
00181         delete_button = QtGui.QPushButton('Delete')
00182         title_layout.addWidget(delete_button)
00183         delete_button.setMaximumWidth(50)
00184         self.connect(delete_button, QtCore.SIGNAL('clicked()'), self.slot_delete )        
00185         
00186         
00187         self.connect(self.draw_widget, QtCore.SIGNAL('sigPolyChanged'), self.slot_update_polygons)
00188         self.connect(self.draw_widget, QtCore.SIGNAL('sigPolyLabelChanged'), self.slot_update_polygon_label)
00189         self.connect(self.draw_widget, QtCore.SIGNAL('sigDefineGroundPlane'), self.slot_define_ground_plane)
00190 
00191         left_layout.addLayout(title_layout)
00192         
00193         #second row:
00194         row2_layout = QtGui.QHBoxLayout()
00195         left_layout.addLayout(row2_layout)
00196         
00197 
00198         label = QtGui.QLabel("Id:")
00199         row2_layout.addWidget(label)        
00200         self.id_label = QtGui.QLabel("")
00201         row2_layout.addWidget(self.id_label)        
00202         
00203         self.add_line_edit('Surface: ID:',row2_layout,'surface_id')
00204         self.add_line_edit('Height',row2_layout,'surface_height')
00205         
00206         
00207         label = QtGui.QLabel("Type: ")
00208         row2_layout.addWidget(label)
00209         combobox = QtGui.QComboBox()
00210         combobox.addItem("Table Office", QtCore.QVariant("table_office"))
00211         combobox.addItem("Table Dorm", QtCore.QVariant("table_dorm"))
00212         combobox.addItem("Table House", QtCore.QVariant("table_house"))
00213         combobox.addItem("Shelf Office", QtCore.QVariant("shelf_office"))
00214         combobox.addItem("Shelf Dorm", QtCore.QVariant("shelf_dorm"))
00215         combobox.addItem("Shelf House", QtCore.QVariant("shelf_house"))
00216         self.connect(combobox, QtCore.SIGNAL('currentIndexChanged(int)'), self.slot_update_surface_type)  
00217         row2_layout.addWidget(combobox)
00218         self.surface_type_combobox = combobox;
00219         
00220         self.add_line_edit('Camera: Height:',row2_layout,'camera_height')
00221         self.add_line_edit('Camera: Angle:',row2_layout,'camera_angle')
00222         
00223         #####################################
00224         #thrid row:
00225         row3_layout = QtGui.QHBoxLayout()
00226         left_layout.addLayout(row3_layout)
00227         
00228         #checkboxes:
00229         button = QtGui.QPushButton("&gen'n'save features")
00230         row3_layout.addWidget(button)
00231         self.connect(button, QtCore.SIGNAL('clicked()'), self.slot_generate_save_features )        
00232         
00233         checkbox = QtGui.QCheckBox('&Training Set')
00234         row3_layout.addWidget(checkbox)
00235         self.connect(checkbox, QtCore.SIGNAL('stateChanged(int)'), self.slot_update_training_set)  
00236         self.checkbox_training_set = checkbox
00237         
00238         checkbox = QtGui.QCheckBox('Te&st Set')
00239         row3_layout.addWidget(checkbox)
00240         self.connect(checkbox, QtCore.SIGNAL('stateChanged(int)'), self.slot_update_test_set)
00241         self.checkbox_test_set = checkbox  
00242         
00243         checkbox = QtGui.QCheckBox('Labels, Groundp. checked')
00244         row3_layout.addWidget(checkbox)
00245         self.connect(checkbox, QtCore.SIGNAL('stateChanged(int)'), self.slot_update_is_labeled)
00246         self.checkbox_is_labeled = checkbox                         
00247         
00248         button = QtGui.QPushButton("Train'n'save Classifiers (training set)")
00249         row3_layout.addWidget(button)
00250         self.connect(button, QtCore.SIGNAL('clicked()'), self.slot_train_and_save_Classifiers )
00251         
00252         button = QtGui.QPushButton('Test Classifiers (on current)')
00253         row3_layout.addWidget(button)
00254         self.connect(button, QtCore.SIGNAL('clicked()'), self.slot_test_Classifiers )
00255         
00256         button = QtGui.QPushButton('Test Classifiers (on testset)')
00257         row3_layout.addWidget(button)
00258         self.connect(button, QtCore.SIGNAL('clicked()'), self.slot_test_Classifiers_on_testset )        
00259         
00260         button = QtGui.QPushButton('Load Classifiers')
00261         row3_layout.addWidget(button)
00262         self.connect(button, QtCore.SIGNAL('clicked()'), self.slot_load_Classifiers )
00263  
00264 #        button = QtGui.QPushButton('Save Classifier')
00265 #        row3_layout.addWidget(button)
00266 #        self.connect(button, QtCore.SIGNAL('clicked()'), self.slot_save_Classifier )                       
00267         
00268         #####################################
00269         
00270         left_layout.addWidget(self.draw_widget)
00271         
00272         
00273         self.right_layout = QtGui.QVBoxLayout()
00274         self.right_layout.setAlignment(QtCore.Qt.AlignTop)
00275         
00276         self.outer_layout = QtGui.QHBoxLayout()
00277         self.outer_layout.addLayout(left_layout)
00278         self.outer_layout.addLayout(self.right_layout)
00279         
00280 
00281         
00282         self.polygon_comboboxes = []
00283         self.add_polygon_combobox()
00284 
00285         self.slot_update_polygons(self.current_dataset.polygons,0)
00286         
00287         
00288         self.setLayout(self.outer_layout)
00289         
00290         
00291         self.resize(900, 700) 
00292         self.load_values_from_dataset()
00293         
00294         self.init_in_progress = False
00295         
00296         #at startup, display newest:
00297         self.slot_last_dataset()
00298     
00299     
00300     def slot_update_training_set(self, checkState):
00301         if checkState:
00302             self.current_dataset.is_training_set = True
00303         else:
00304             self.current_dataset.is_training_set = False
00305             
00306     def slot_update_test_set(self, checkState):
00307         if checkState:
00308             self.current_dataset.is_test_set = True
00309         else:
00310             self.current_dataset.is_test_set = False
00311             
00312     def slot_update_is_labeled(self, checkState):
00313         if checkState:
00314             self.current_dataset.is_labeled = True
00315         else:
00316             self.current_dataset.is_labeled = False
00317     
00318     def closeEvent(self, x):
00319         print "Exit: saving database..."
00320         self.slot_save()      
00321         
00322     def slot_import_image(self):
00323         fileName = QtGui.QFileDialog.getOpenFileName(self,"Open Image", self.path, "Image Files (*.png)")
00324         print "Import image into new dataset:" + fileName
00325         
00326         name = ut.formatted_time()
00327         
00328         new_dataset = scan_dataset.scan_dataset()
00329         new_dataset.id = name
00330         new_dataset.image_filename = 'data/'+name+'_image.png'
00331         shutil.copy(fileName,self.path+'/'+new_dataset.image_filename)
00332         
00333         self.scans_database.add_dataset(new_dataset)
00334 
00335         #proceed to new dataset: 
00336         while True == self.slot_next_dataset():
00337             pass        
00338         
00339         
00340     def add_line_edit(self,label, layout, variable):
00341         label = QtGui.QLabel(label)
00342         line_edit = QtGui.QLineEdit()
00343         line_edit.setMinimumWidth(80)
00344         self.line_edits.append((line_edit,variable))
00345         layout.addWidget(label)
00346         layout.addWidget(line_edit)
00347         self.connect(line_edit, QtCore.SIGNAL('textEdited (const QString&)'), self.slot_line_edit_changed ) 
00348         return line_edit      
00349         
00350     def slot_line_edit_changed(self,text):
00351         if True == self.init_in_progress:
00352             return
00353         
00354         for (line_edit, variable) in self.line_edits:
00355             self.current_dataset.dict[variable] = str(line_edit.text())
00356         
00357     def slot_next_dataset(self):
00358         dataset = self.scans_database.get_next_dataset()
00359         if False != dataset:
00360             self.current_dataset = dataset
00361             self.load_values_from_dataset()
00362             return True
00363         return False
00364         
00365     def slot_prev_dataset(self):
00366         dataset = self.scans_database.get_prev_dataset()
00367         if False != dataset:
00368             self.current_dataset = dataset
00369             self.load_values_from_dataset()
00370             return True
00371         return False
00372     
00373     def slot_first_dataset(self):
00374         dataset = self.scans_database.get_first_dataset()
00375         if False != dataset:
00376             self.current_dataset = dataset
00377             self.load_values_from_dataset()
00378             return True
00379         return False  
00380          
00381     def slot_last_dataset(self):
00382         dataset = self.scans_database.get_last_dataset()
00383         if False != dataset:
00384             self.current_dataset = dataset
00385             self.load_values_from_dataset()
00386             return True
00387         return False              
00388             
00389             
00390     def load_values_from_dataset(self):
00391         self.init_in_progress = True
00392         
00393         self.id_label.setText(self.current_dataset.id)
00394         
00395         for (line_edit, variable) in self.line_edits:
00396             line_edit.setText(self.current_dataset.dict[variable])
00397             
00398         for index, box in enumerate(self.polygon_comboboxes):
00399             if index < len(self.current_dataset.polygons):
00400                 print str(index) + " load label:" + self.current_dataset.polygons[index].get_label()
00401                 boxindex = box.findData(QtCore.QVariant(self.current_dataset.polygons[index].get_label()))
00402                 box.setCurrentIndex(boxindex)
00403             else: #set default to first:
00404                 box.setCurrentIndex(0)
00405                 
00406                 
00407         box = self.surface_type_combobox
00408         boxindex = box.findData(QtCore.QVariant(self.current_dataset.surface_type))
00409         box.setCurrentIndex(boxindex)
00410         
00411         print self.current_dataset.is_training_set
00412         if self.current_dataset.is_training_set:
00413             self.checkbox_training_set.setCheckState(QtCore.Qt.Checked)
00414         else:
00415             self.checkbox_training_set.setCheckState(QtCore.Qt.Unchecked)
00416             
00417         if self.current_dataset.is_test_set:
00418             self.checkbox_test_set.setCheckState(QtCore.Qt.Checked)
00419         else:
00420             self.checkbox_test_set.setCheckState(QtCore.Qt.Unchecked)
00421         
00422         if self.current_dataset.is_labeled:
00423             self.checkbox_is_labeled.setCheckState(QtCore.Qt.Checked)
00424         else:
00425             self.checkbox_is_labeled.setCheckState(QtCore.Qt.Unchecked)
00426         
00427         #hide button if there is no 3d data:
00428         print self.current_dataset.scan_filename
00429         if '' == self.current_dataset.scan_filename:
00430             self.display_3d_button.setEnabled(False)
00431             self.display_3d_spheres_button.setEnabled(False)
00432             self.display_intensity_button.setEnabled(False)
00433         else:
00434             self.display_3d_button.setEnabled(True)
00435             self.display_3d_spheres_button.setEnabled(True)
00436             self.display_intensity_button.setEnabled(True)
00437     
00438         self.display_mode = 'image'
00439         self.draw_widget.set_polygons(self.current_dataset.polygons)
00440         self.draw_widget.set_image(self.scans_database.get_path() + '/' + self.current_dataset.image_filename)
00441         
00442         self.init_in_progress = False
00443             
00444     def slot_take_artag_image(self):
00445         if False == self.scanner:
00446             self.scanner = scanner.scanner(self.config)
00447         if False == self.processor:
00448             self.processor = processor.processor(self.config)
00449         
00450         img = self.scanner.take_artag_image()
00451         self.current_dataset.image_artag_filename = self.scanner.save_artag_image(self.current_dataset.id)
00452         
00453         self.slot_save() #save for consistency with files
00454         
00455         if self.processor.read_artag(img).any():
00456             print "SUCCESS in reading ARTag"
00457         else:
00458             print "FAILURE in reading ARTag - try again!"
00459         
00460         
00461             
00462     def slot_take_scan(self):
00463         
00464         #save database, let scanner add dataset, reload it then
00465         self.slot_save()
00466         
00467         if False == self.scanner:
00468             self.scanner = scanner.scanner(self.config)
00469         if False == self.processor:
00470             self.processor = processor.processor(self.config)
00471         
00472         name = ut.formatted_time()
00473         self.scanner.capture_and_save(name)
00474         #self.processor.load_raw_data(name)
00475         #self.processor.load_metadata(name)
00476         #self.processor.process_raw_data()
00477         #self.processor.save_mapped_image(name)
00478         #self.processor.display_all_data()
00479         print 'scan ' + name + ' taken'
00480         
00481         self.scans_database.load(self.path,'database.pkl')
00482         
00483         #proceed to new scan: 
00484         while True == self.slot_next_dataset():
00485             pass
00486         
00487     def slot_display_intensity(self):
00488         if self.display_mode != 'intensities':
00489             if False == self.processor:
00490                 self.processor = processor.processor(self.config)
00491                 
00492             #reset ground plane:
00493             self.current_dataset.ground_plane_normal = ''
00494             self.current_dataset.ground_plane_three_points = ''
00495             self.slot_save()    
00496                 
00497             
00498             self.processor.load_data(self.current_dataset.id)
00499             self.processor.process_intensities()
00500             filename = self.processor.save_intensity_image(self.current_dataset.id)
00501             
00502             #self.processor.display_intensities()
00503             
00504             self.display_mode = 'intensities'
00505             self.draw_widget.set_image(filename)
00506         else:
00507             #display normal image
00508             
00509             self.display_mode = 'image'
00510             self.draw_widget.set_image(self.scans_database.get_path() + '/' + self.current_dataset.image_filename)
00511             
00512     def slot_display_features(self):
00513         if self.display_mode != 'features':
00514             if False == self.processor:
00515                 self.processor = processor.processor(self.config)
00516                 
00517             self.processor.load_data(self.current_dataset.id)
00518             self.processor.process_intensities()
00519             filename = self.processor.save_intensity_image(self.current_dataset.id)
00520             self.display_mode = 'features'
00521             self.draw_widget.set_image(filename)
00522             
00523         else:
00524             #display normal image
00525             self.display_mode = 'image'
00526             self.draw_widget.set_image(self.scans_database.get_path() + '/' + self.current_dataset.image_filename)
00527                  
00528             
00529     def slot_display_labels(self):
00530         if self.display_mode != 'labels':
00531             if False == self.processor:
00532                 self.processor = processor.processor(self.config)
00533                 
00534             self.processor.load_data(self.current_dataset.id)
00535             self.processor.process_labels(self.display_3d_type)
00536             filename = self.processor.save_labels_image(self.display_3d_type)
00537             
00538             self.draw_widget.set_image(filename)
00539             self.display_mode = 'labels'
00540         else:
00541             #display normal image
00542             self.draw_widget.set_image(self.scans_database.get_path() + '/' + self.current_dataset.image_filename)
00543             self.display_mode = 'image'               
00544             
00545     def slot_display_stats(self):
00546         if False == self.processor:
00547             self.processor = processor.processor(self.config)
00548             
00549         self.processor.load_data(self.current_dataset.id)
00550         self.processor.display_stats()
00551          
00552     def slot_display_global_stats(self):
00553         if False == self.processor:
00554             self.processor = processor.processor(self.config)
00555             
00556         self.processor.load_data(self.current_dataset.id)
00557         self.processor.display_stats(True)      
00558         
00559         
00560     def slot_display_3d_spheres(self):  
00561         self.slot_display_3d(True)   
00562         
00563     def slot_display_3d(self, spheres = False):
00564 
00565         if False == self.processor:       
00566             self.processor = processor.processor(self.config)
00567             
00568         #save data first so the processor can load it:
00569         self.slot_save()    
00570             
00571         self.processor.load_data(self.current_dataset.id)
00572         #self.processor.create_polygon_images()
00573         self.processor.process_raw_data()
00574         #pc.save_mapped_image(name)
00575         self.processor.display_3d(self.display_3d_type, spheres)
00576         
00577     def slot_train_and_save_Classifiers(self):
00578 
00579         if False == self.processor:       
00580             self.processor = processor.processor(self.config)
00581             
00582         #save data first so the processor can load it:
00583         self.slot_save()    
00584             
00585         self.processor.load_data(self.current_dataset.id)
00586         self.processor.train_and_save_Classifiers()   
00587         
00588     def slot_generate_save_features(self):
00589 
00590         if False == self.processor:       
00591             self.processor = processor.processor(self.config)
00592             
00593         #save data first so the processor can load it:
00594         self.slot_save()    
00595             
00596         self.processor.load_data(self.current_dataset.id)
00597         self.processor.generate_save_features()   
00598         
00599         
00600     def slot_test_Classifiers(self):
00601         if False == self.processor:       
00602             self.processor = processor.processor(self.config)
00603         self.slot_save()    #save data first so the processor can load it:
00604         self.processor.load_data(self.current_dataset.id)
00605         self.processor.train_and_save_Classifiers()
00606         self.processor.test_Classifiers()   
00607         
00608     def slot_test_Classifiers_on_testset(self):
00609         if False == self.processor:       
00610             self.processor = processor.processor(self.config)
00611         self.slot_save()    #save data first so the processor can load it:
00612         self.processor.load_data(self.current_dataset.id)
00613         self.processor.train_and_save_Classifiers()
00614         self.processor.test_classifiers_on_testset()          
00615       
00616     def slot_load_Classifiers(self):
00617         if False == self.processor:       
00618             self.processor = processor.processor(self.config)
00619         self.processor.load_Classifiers()   
00620         
00621     def slot_save_Classifier(self):
00622         if False == self.processor:       
00623             print 'ERROR: no processor object exists -> no Classifier to save!'
00624             return
00625         self.processor.save_Classifier()      
00626             
00627     def add_polygon_combobox(self):
00628         combobox = QtGui.QComboBox()
00629         combobox.addItem("Object", QtCore.QVariant("object"))
00630         combobox.addItem("Surface", QtCore.QVariant("surface"))
00631         combobox.addItem("Region of Interest (ROI)", QtCore.QVariant("roi"))
00632         combobox.addItem("Background", QtCore.QVariant("background"))
00633         combobox.addItem("Visible Surface-Edge", QtCore.QVariant("edge"))
00634         combobox.addItem("Wall-Surface-Edge", QtCore.QVariant("edge_up"))
00635         combobox.addItem("Downward-Surface-Edge", QtCore.QVariant("edge_down"))
00636         combobox.setCurrentIndex(0)
00637 
00638         self.connect(combobox, QtCore.SIGNAL('currentIndexChanged(int)'), self.slot_update_polygon_labels)
00639         self.polygon_comboboxes.append(combobox)
00640         self.right_layout.addWidget(combobox, QtCore.Qt.AlignTop)
00641         self.slot_update_polygon_labels()
00642         
00643         
00644     def slot_delete(self):
00645         #delete scan-files:
00646         if  os.path.isfile(self.current_dataset.scan_filename):
00647             os.remove(self.path + '/' + self.current_dataset.scan_filename);
00648         if os.path.isfile(self.current_dataset.image_filename):
00649             os.remove(self.path + '/' + self.current_dataset.image_filename);
00650         if os.path.isfile(self.current_dataset.image_artag_filename):
00651             os.remove(self.path + '/' + self.current_dataset.image_artag_filename);            
00652         #delete metadata
00653         self.current_dataset  = self.scans_database.delete_current_dataset()
00654         self.load_values_from_dataset()
00655         self.slot_save() #save for consistency with files
00656         
00657     def slot_save(self):
00658         dumpObj(self.current_dataset)
00659         #for poly in self.draw_widget.get_polygons():
00660         #    dumpObj(poly)
00661         #self.slot_update_polygons(self.draw_widget.get_polygons(), 1)
00662         self.scans_database.save()
00663         
00664     def slot_update_surface_type(self):
00665         if True == self.init_in_progress:
00666             return   
00667         box = self.surface_type_combobox
00668         self.current_dataset.surface_type = str(box.itemData(box.currentIndex()).toString())
00669         
00670     def slot_update_display_3d_type(self):
00671         if True == self.init_in_progress:
00672             return          
00673         box = self.display_3d_type_combobox
00674         self.display_3d_type = str(box.itemData(box.currentIndex()).toString())  
00675         
00676     def slot_update_polygon_label(self, index, label):
00677         if True == self.init_in_progress:
00678             return       
00679         
00680         box = self.polygon_comboboxes[index]
00681         boxindex = box.findData(QtCore.QVariant(label))
00682         box.setCurrentIndex(boxindex)  
00683         
00684         self.draw_widget.update()    
00685         
00686     def slot_update_polygon_labels(self):
00687         if True == self.init_in_progress:
00688             return       
00689         
00690         for index, box in enumerate(self.polygon_comboboxes):
00691             if index < len(self.current_dataset.polygons):
00692                 self.current_dataset.polygons[index].set_label(str(box.itemData(box.currentIndex()).toString()))
00693                 print str(index) + " xx " + str(box.itemData(box.currentIndex()).toString()) 
00694                 
00695         self.draw_widget.update()         
00696     
00697     def slot_update_polygons(self, polygons, current_index):
00698 
00699         while len(self.polygon_comboboxes) < len(polygons):
00700             self.add_polygon_combobox()
00701 
00702         #self.polygon_comboboxes[self.current_polygon_index].x()
00703         for index, box in enumerate(self.polygon_comboboxes):
00704             if index < len(polygons):
00705                 self.polygon_comboboxes[index].show()
00706             else:
00707                 self.polygon_comboboxes[index].hide() 
00708         self.update()
00709         
00710     def paintEvent(self, event):
00711         painter = QtGui.QPainter()
00712         painter.begin(self)
00713         
00714         x = self.polygon_comboboxes[self.draw_widget.get_current_polygon_index()].x()    
00715         y = self.polygon_comboboxes[self.draw_widget.get_current_polygon_index()].y() 
00716         color = QtGui.QColor(255,0,0)
00717         painter.setPen(color)
00718         painter.setBrush(color)
00719         painter.drawEllipse(QtCore.QRectF(x-8,y+8,6,6))
00720             
00721         painter.end()
00722         
00723     def get_display_mode(self):
00724         return self.display_mode
00725     
00726     def slot_define_ground_plane(self, ground_plane_points):
00727         #assumes that intensity image is loaded in processor!
00728         (self.current_dataset.ground_plane_normal, self.current_dataset.ground_plane_three_points) = self.processor.get_3d_plane_normal(ground_plane_points)
00729         self.slot_display_intensity() #switch back to image mode
00730 
00731 class draw_widget(QtGui.QLabel):
00732     
00733     
00734     ground_plane_points = []
00735     
00736     def __init__(self,polygons, image_filename, parent=None):
00737         QtGui.QWidget.__init__(self, parent)
00738 
00739         self.scaleFactor = False #init is done later
00740 
00741         self.setBackgroundRole(QtGui.QPalette.Base)
00742         #self.setSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Ignored)
00743         self.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
00744         self.setScaledContents(True)
00745 
00746 
00747         self.set_polygons(polygons)
00748         self.set_image(image_filename)
00749         
00750         self.setScaleFactor(0.8)
00751        
00752     def setScaleFactor(self, f):
00753         self.scaleFactor = f
00754         self.updateImageSize()
00755         
00756     def updateImageSize(self):
00757         if self.parent().get_display_mode() == 'intensities' or self.parent().get_display_mode() == 'features':
00758             self.scaleFactor = 1 
00759         else:
00760             self.scaleFactor = 0.8      
00761             self.parent().resize(900, 700) 
00762         
00763         self.setMinimumHeight(self.image.height() * self.scaleFactor)
00764         self.setMinimumWidth(self.image.width() * self.scaleFactor)
00765         self.setMaximumHeight(self.image.height() * self.scaleFactor)
00766         self.setMaximumWidth(self.image.width() * self.scaleFactor)
00767         
00768         pixmap = QtGui.QPixmap.fromImage(self.image)
00769         self.resize(self.scaleFactor * pixmap.size());
00770         self.setPixmap(pixmap);
00771         
00772         
00773     def set_polygons(self, polygons):
00774         self.polygons = polygons
00775         self.current_polygon_index = 0
00776         self.update()
00777         self.emit(QtCore.SIGNAL("sigPolyChanged"), self.polygons, self.current_polygon_index)         
00778         
00779     def set_image(self, filename):
00780         print filename
00781         if os.path.isfile(filename):
00782             self.image = QtGui.QImage(filename)
00783         else:
00784             self.image = QtGui.QImage('noimage.png')
00785         
00786         self.updateImageSize()
00787         self.update()
00788         
00789     def paintEvent(self, event):
00790         # draw image as label-pixmap
00791         QtGui.QLabel.paintEvent(self,event) 
00792         painter = QtGui.QPainter()
00793         painter.begin(self)
00794         if self.parent().get_display_mode() == 'image' or self.parent().get_display_mode() == 'labels':
00795             color = QtGui.QColor(0,0,255)
00796             color_surface = QtGui.QColor(0,255,0)
00797             color_roi = QtGui.QColor(255,255,255)
00798             color_edge = QtGui.QColor(255,255,0)
00799             color_edge_up = QtGui.QColor(255,255,255)
00800             color_edge_down = QtGui.QColor(255,150,255)
00801             color_background = QtGui.QColor(255,0,255)
00802             color_current = QtGui.QColor(255,0,0)
00803     
00804             for index, polygon in enumerate(self.polygons):
00805                 
00806                 last_point = (-1,-1)
00807                 first = True;
00808                 if self.current_polygon_index != index or self.parent().get_display_mode() != 'image':
00809                     if polygon.get_label() == 'surface':
00810                         painter.setPen(color_surface)
00811                     elif polygon.get_label() == 'roi':
00812                         painter.setPen(color_roi)                        
00813                     elif polygon.get_label() == 'edge':
00814                         painter.setPen(color_edge)
00815                     elif polygon.get_label() == 'edge_up':
00816                         painter.setPen(color_edge_up)
00817                     elif polygon.get_label() == 'edge_down':
00818                         painter.setPen(color_edge_down)
00819                     elif polygon.get_label() == 'background':
00820                         painter.setPen(color_background)                    
00821                     else:
00822                         painter.setPen(color)
00823                 else:
00824                     painter.setPen(color_current)
00825     
00826                 for point in polygon.get_points():
00827                     if False == first:
00828                         painter.drawLine(QtCore.QPointF(point[0],point[1]) * self.scaleFactor, QtCore.QPointF(last_point[0],last_point[1]) * self.scaleFactor)
00829                     last_point = point
00830                     first = False
00831                     
00832                 
00833                 if (self.parent().get_display_mode() != 'image'  or self.current_polygon_index != index ) and polygon.get_type() == 'polygon' and len(polygon.get_points()) :
00834                     painter.drawLine(QtCore.QPointF(last_point[0],last_point[1]) * self.scaleFactor, QtCore.QPointF(polygon.get_points()[0][0],polygon.get_points()[0][1]) * self.scaleFactor)
00835                 else:
00836                     for point in polygon.get_points():
00837                         painter.drawEllipse(QtCore.QRectF(point[0] * self.scaleFactor-3,point[1] * self.scaleFactor-3,6,6))
00838                 
00839         elif self.parent().get_display_mode() == 'intensities':
00840             color = QtGui.QColor(255,0,255)
00841             painter.setPen(color)
00842             for point in self.ground_plane_points:
00843                 painter.drawEllipse(QtCore.QRectF(point[0] * self.scaleFactor-3,point[1] * self.scaleFactor-3,6,6))
00844         painter.end()
00845 
00846     
00847     def mousePressEvent(self,event):
00848         
00849         if self.hasFocus():
00850             if self.parent().get_display_mode() == 'image':
00851                 if event.button() == QtCore.Qt.LeftButton:
00852                     #print 'coords:', x,'  ',y
00853                     point = (event.x() / self.scaleFactor, event.y() / self.scaleFactor)
00854                     self.polygons[self.current_polygon_index].add_point(point)
00855                     self.update()
00856                     self.emit(QtCore.SIGNAL("sigPolyChanged"), self.polygons, self.current_polygon_index)
00857                 if  event.button() == QtCore.Qt.RightButton:
00858                     if False == self.polygons[self.current_polygon_index].is_empty():
00859                         self.polygons[self.current_polygon_index].delete_last_point()
00860                         self.update()
00861                         self.emit(QtCore.SIGNAL("sigPolyChanged"), self.polygons, self.current_polygon_index)
00862             elif self.parent().get_display_mode() == 'intensities':
00863                
00864                 point = (event.x() / self.scaleFactor, event.y() / self.scaleFactor)
00865                 print 'point:', point
00866                 if True == self.parent().processor.check_3d_plane_point(point):
00867                     self.ground_plane_points.append(point)
00868                     if len(self.ground_plane_points) < 3:
00869                         self.update()
00870                     else:
00871                         self.emit(QtCore.SIGNAL("sigDefineGroundPlane"), self.ground_plane_points)
00872                         self.ground_plane_points = []
00873                         
00874                      
00875             elif self.parent().get_display_mode() == 'features':   
00876                 point = (event.x() / self.scaleFactor, event.y() / self.scaleFactor)
00877                 if True == self.parent().processor.check_3d_plane_point(point):
00878                     print 'point:', point
00879                     point3d = self.parent().processor.get_3d_point(point)
00880                     print 'point3d',point3d
00881                     
00882                     index = self.parent().processor.get_3d_point_index_in_unrotated(point3d)
00883                     self.parent().processor.load_data(self.parent().current_dataset.id)
00884                     self.parent().processor.process_raw_data()
00885                     self.parent().processor.features.prepare([index])
00886                     self.parent().processor.feature_type = 'gaussian_histograms'
00887                     fv = self.parent().processor.features.get_featurevector(index,0)
00888                     print 'fv',fv
00889                     self.parent().processor.display_featurevector(fv)
00890                     
00891                     #reload intensity data for next click
00892                     self.parent().processor.load_data(self.parent().current_dataset.id)
00893                     self.parent().processor.process_intensities()
00894                     
00895                     #print 'fv:', self.parent().processor.get_point_featurevector(index, self.parent().processor.pts3d_int)
00896                     #print 'WARNING: THIS IS NOT WORKING YET BECAUSE OF MISSING INTENSITY INDEX MAPPING FOR GRAZEEFFCT REMOVED PTS'
00897         else:
00898             self.setFocus()
00899 
00900     def mouseDoubleClickEvent(self,event):
00901         if self.parent().get_display_mode() == 'image':
00902             if event.button() == QtCore.Qt.LeftButton:
00903                 self.start_new_polygon()
00904                 self.update()
00905                 self.emit(QtCore.SIGNAL("sigPolyChanged"), self.polygons, self.current_polygon_index)
00906                 
00907     def start_new_polygon(self):
00908         if False == self.polygons[self.current_polygon_index].is_empty():
00909            # if self.current_polygon_index == len(self.polygons) - 1:
00910             self.polygons.append(label_object.label_object()) #last one, append new
00911             self.current_polygon_index = len(self.polygons) - 1
00912             print "new poly index: ", self.current_polygon_index
00913             
00914     def delete_empty_polygon(self):
00915         if True == self.polygons[self.current_polygon_index].is_empty():
00916             #and it isn't the only one:
00917             if 1 != len(self.polygons):
00918                 del self.polygons[self.current_polygon_index]
00919                 if 0 != self.current_polygon_index:
00920                     self.current_polygon_index -= 1
00921                 print "new poly index: ", self.current_polygon_index
00922                 return True
00923         return False
00924     
00925     def keyPressEvent(self, event):
00926         key = event.key()
00927         if key == QtCore.Qt.Key_Right:
00928             print 'right'
00929             if self.current_polygon_index < len(self.polygons) - 1:
00930                 self.delete_empty_polygon()
00931                 self.current_polygon_index += 1
00932                 print "czurrent poly index: ", self.current_polygon_index
00933             else:
00934                 self.start_new_polygon()
00935                 self.parent().slot_update_polygon_labels()
00936             self.update()
00937             self.emit(QtCore.SIGNAL("sigPolyChanged"), self.polygons, self.current_polygon_index)
00938         elif key == QtCore.Qt.Key_Left:
00939             print 'left'
00940             if self.current_polygon_index > 0:
00941                 if False == self.delete_empty_polygon():
00942                     self.current_polygon_index -= 1
00943                 print "current poly index: ", self.current_polygon_index
00944             self.update()
00945             self.emit(QtCore.SIGNAL("sigPolyChanged"), self.polygons, self.current_polygon_index)
00946         elif key == QtCore.Qt.Key_O:
00947             print 'o'
00948             self.emit(QtCore.SIGNAL("sigPolyLabelChanged"), self.current_polygon_index, 'object')      
00949         elif key == QtCore.Qt.Key_S:
00950             print 's'
00951             self.emit(QtCore.SIGNAL("sigPolyLabelChanged"), self.current_polygon_index, 'surface')    
00952         elif key == QtCore.Qt.Key_R:
00953             print 'r'
00954             self.emit(QtCore.SIGNAL("sigPolyLabelChanged"), self.current_polygon_index, 'roi')                
00955         elif key == QtCore.Qt.Key_B:
00956             print 'b'
00957             self.emit(QtCore.SIGNAL("sigPolyLabelChanged"), self.current_polygon_index, 'background')    
00958         elif key == QtCore.Qt.Key_E:
00959             print 'e'
00960             self.emit(QtCore.SIGNAL("sigPolyLabelChanged"), self.current_polygon_index, 'edge')  
00961         elif key == QtCore.Qt.Key_U:
00962             print 'u'
00963             self.emit(QtCore.SIGNAL("sigPolyLabelChanged"), self.current_polygon_index, 'edge_up') 
00964         elif key == QtCore.Qt.Key_D:
00965             print 'd'
00966             self.emit(QtCore.SIGNAL("sigPolyLabelChanged"), self.current_polygon_index, 'edge_down')   
00967         elif key == QtCore.Qt.Key_Plus:
00968             print '+'
00969             self.setScaleFactor(self.scaleFactor * 1.25)
00970             self.update()     
00971         elif key == QtCore.Qt.Key_Minus:
00972             print '-'
00973             self.setScaleFactor(self.scaleFactor * 0.8)
00974             self.update()                                                               
00975         else:
00976             QtGui.QWidget.keyPressEvent(self, event)
00977     
00978     def get_polygons(self):
00979         return self.polygons
00980     
00981     def get_current_polygon_index(self):
00982         return self.current_polygon_index
00983     
00984     
00985     
00986     
00987     
00988 if __name__ == "__main__":
00989     app = QtGui.QApplication(sys.argv)
00990     labeling_tool = labeling_tool('/home/martin/robot1_data/usr/martin/laser_camera_segmentation/labeling');#
00991 
00992     labeling_tool.show()
00993     sys.exit(app.exec_())


laser_camera_segmentation
Author(s): Martin Schuster, Advisor: Prof. Charlie Kemp, Lab: Healthcare Robotics Lab at Georgia Tech
autogenerated on Wed Nov 27 2013 11:56:44