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


clutter_segmentation
Author(s): Jason Okerman, Martin Schuster, Advisors: Prof. Charlie Kemp and Jim Regh, Lab: Healthcare Robotics Lab at Georgia Tech
autogenerated on Wed Nov 27 2013 12:07:15