@@ -396,16 +396,11 @@ void LabelImages::delete_selected_annotation(){
396396}
397397
398398void LabelImages::change_annotation_selection_by_mouse (double x, double y){
399- if (m_annotations.size () == 0 ){
400- return ;
401- }
402- // no annotation image loaded
403- if (source_image_width == 0 || source_image_height == 0 ){
399+ // no image or no annotation
400+ if (source_image_width == 0 || source_image_height == 0 || m_annotations.size () == 0 ){
404401 return ;
405402 }
406-
407- auto & cur_ui_label = FORM_LABEL.slug ();
408-
403+
409404 double closest_distance = DBL_MAX;
410405 for (size_t i = 0 ; i < m_annotations.size (); i++){
411406 ImageFloatBox float_box = pixelbox_to_floatbox (source_image_width, source_image_height, m_annotations[i].mask_box );
@@ -419,7 +414,46 @@ void LabelImages::change_annotation_selection_by_mouse(double x, double y){
419414 }
420415
421416 auto new_label = m_annotations[m_selected_obj_idx].label ;
422- if (cur_ui_label != new_label){
417+ if (FORM_LABEL.slug () != new_label){
418+ FORM_LABEL.set_by_slug (new_label);
419+ }
420+ }
421+
422+ void LabelImages::select_prev_annotation (){
423+ // no image or no annotation
424+ if (source_image_width == 0 || source_image_height == 0 || m_annotations.size () == 0 ){
425+ return ;
426+ }
427+
428+ if (m_selected_obj_idx >= m_annotations.size ()){
429+ m_selected_obj_idx = m_annotations.size () - 1 ;
430+ } else if (m_selected_obj_idx == 0 ){
431+ m_selected_obj_idx = m_annotations.size () - 1 ;
432+ } else {
433+ m_selected_obj_idx--;
434+ }
435+
436+ auto new_label = m_annotations[m_selected_obj_idx].label ;
437+ if (FORM_LABEL.slug () != new_label){
438+ FORM_LABEL.set_by_slug (new_label);
439+ }
440+ }
441+ void LabelImages::select_next_annotation (){
442+ // no image or no annotation
443+ if (source_image_width == 0 || source_image_height == 0 || m_annotations.size () == 0 ){
444+ return ;
445+ }
446+
447+ if (m_selected_obj_idx >= m_annotations.size ()){
448+ m_selected_obj_idx = 0 ;
449+ } else if (m_selected_obj_idx + 1 == m_annotations.size ()){
450+ m_selected_obj_idx = 0 ;
451+ } else {
452+ m_selected_obj_idx++;
453+ }
454+
455+ auto new_label = m_annotations[m_selected_obj_idx].label ;
456+ if (FORM_LABEL.slug () != new_label){
423457 FORM_LABEL.set_by_slug (new_label);
424458 }
425459}
@@ -479,21 +513,44 @@ LabelImages_Widget::LabelImages_Widget(
479513 embedding_info_row->addWidget (new QLabel (" <b>Image Embedding File:</b> " , this ));
480514 embedding_info_row->addWidget (m_embedding_info_label);
481515
482- QPushButton* button = new QPushButton (" Delete Last Mask" , scroll_inner);
483- scroll_layout->addWidget (button);
484- connect (button, &QPushButton::clicked, this , [this ](bool ){
516+ QHBoxLayout* button_row = new QHBoxLayout ();
517+ scroll_layout->addLayout (button_row);
518+
519+ QPushButton* delete_anno_button = new QPushButton (" Delete Selected Annotation" , scroll_inner);
520+ button_row->addWidget (delete_anno_button, 1 );
521+
522+ QPushButton* pre_anno_button = new QPushButton (" Prev Annotation" , scroll_inner);
523+ button_row->addWidget (pre_anno_button, 1 );
524+
525+ QPushButton* next_anno_button = new QPushButton (" Next Annotation" , scroll_inner);
526+ button_row->addWidget (next_anno_button, 1 );
527+
528+
529+ // Add all option UI elements defined by LabelImage program.
530+ m_option_widget = program.m_options .make_QtWidget (*scroll_inner);
531+ scroll_layout->addWidget (&m_option_widget->widget ());
532+
533+ QPushButton* compute_embedding_button = new QPushButton (" Compute Image Embeddings (SLOW!)" , scroll_inner);
534+ scroll_layout->addWidget (compute_embedding_button);
535+
536+ connect (delete_anno_button, &QPushButton::clicked, this , [this ](bool ){
485537 auto & program = this ->m_program ;
486538 program.delete_selected_annotation ();
487539 program.update_rendered_objects (this ->m_overlay_set );
488540 });
489541
490- // Add all option UI elements defined by LabelImage program.
491- m_option_widget = program.m_options .make_QtWidget (*scroll_inner);
492- scroll_layout->addWidget (&m_option_widget->widget ());
542+ connect (pre_anno_button, &QPushButton::clicked, this , [this ](bool ){
543+ auto & program = this ->m_program ;
544+ program.select_prev_annotation ();
545+ program.update_rendered_objects (this ->m_overlay_set );
546+ });
547+ connect (next_anno_button, &QPushButton::clicked, this , [this ](bool ){
548+ auto & program = this ->m_program ;
549+ program.select_next_annotation ();
550+ program.update_rendered_objects (this ->m_overlay_set );
551+ });
493552
494- button = new QPushButton (" Compute Image Embeddings (SLOW!)" , scroll_inner);
495- scroll_layout->addWidget (button);
496- connect (button, &QPushButton::clicked, this , [this ](bool ){
553+ connect (compute_embedding_button, &QPushButton::clicked, this , [this ](bool ){
497554 std::string folder_path = QFileDialog::getExistingDirectory (
498555 nullptr , " Open image folder" , " ." ).toStdString ();
499556
0 commit comments