00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
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
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
00055 import os
00056
00057 import label_object, scan_dataset, scans_database
00058
00059
00060 import canner
00061 import processor
00062 import configuration
00063 import util as ut
00064
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
00081 self.config = configuration.configuration(path)
00082
00083 self.scanner = False
00084 self.processor = False
00085
00086
00087
00088 self.scans_database = scans_database.scans_database()
00089 self.scans_database.load(path,'database.pkl')
00090
00091
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
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
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
00244 row3_layout = QtGui.QHBoxLayout()
00245 left_layout.addLayout(row3_layout)
00246
00247
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
00284
00285
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
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
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:
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
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()
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
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
00494
00495
00496
00497
00498 print 'scan ' + name + ' taken'
00499
00500 self.scans_database.load(self.path,'database.pkl')
00501
00502
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
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
00522
00523 self.display_mode = 'intensities'
00524 self.draw_widget.set_image(filename)
00525 else:
00526
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
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
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)
00572 else:
00573 self.processor.process_masks(self.display_3d_type, True)
00574 self.display_mode = 'image'
00575 filename = self.processor.save_masks_image(self.display_3d_type, True)
00576 self.draw_widget.set_image(filename)
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
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
00609 print 'Before process_raw_data'
00610 self.processor.process_raw_data()
00611
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
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
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()
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()
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
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
00692 self.current_dataset = self.scans_database.delete_current_dataset()
00693 self.load_values_from_dataset()
00694 self.slot_save()
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
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
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()
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
00775
00776 self.setBackgroundRole(QtGui.QPalette.Base)
00777
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
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
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
00927 self.parent().processor.load_data(self.parent().current_dataset.id)
00928 self.parent().processor.process_intensities()
00929
00930
00931
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
00945 self.polygons.append(label_object.label_object())
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
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_())