2020#include < fstream>
2121#include < filesystem>
2222#include < cmath>
23+ #include < iomanip>
2324#include " CommonFramework/Globals.h"
2425#include " Common/Cpp/BitmapConversion.h"
2526#include " Common/Cpp/Json/JsonArray.h"
@@ -108,79 +109,6 @@ JsonObject object_annotation_to_json(const ObjectAnnotation& object_annotation){
108109}
109110
110111
111- DrawnBoundingBox::DrawnBoundingBox (LabelImages_Widget& widget, VideoOverlay& overlay)
112- : m_widget(widget)
113- , m_overlay(overlay)
114- {
115- auto & program = m_widget.m_program ;
116- program.X .add_listener (*this );
117- program.Y .add_listener (*this );
118- program.WIDTH .add_listener (*this );
119- program.HEIGHT .add_listener (*this );
120- overlay.add_listener (*this );
121- }
122-
123- DrawnBoundingBox::~DrawnBoundingBox (){
124- detach ();
125- }
126-
127- // called when drawn bounding box changed
128- void DrawnBoundingBox::on_config_value_changed (void * object){
129- auto & program = m_widget.m_program ;
130- std::lock_guard<std::mutex> lg (m_lock);
131- program.update_rendered_objects (m_widget.m_overlay_set );
132- }
133- void DrawnBoundingBox::on_mouse_press (double x, double y){
134- auto & program = m_widget.m_program ;
135- program.WIDTH .set (0 );
136- program.HEIGHT .set (0 );
137- program.X .set (x);
138- program.Y .set (y);
139- m_mouse_start.emplace ();
140- m_mouse_start->first = x;
141- m_mouse_start->second = y;
142- }
143- void DrawnBoundingBox::on_mouse_release (double , double ){
144- m_mouse_start.reset ();
145- auto & m_program = m_widget.m_program ;
146- auto & m_overlay_set = m_widget.m_overlay_set ;
147-
148- m_program.compute_mask (m_overlay_set);
149- }
150-
151- void DrawnBoundingBox::on_mouse_move (double x, double y){
152- auto & program = m_widget.m_program ;
153- if (!m_mouse_start){
154- return ;
155- }
156-
157- double xl = m_mouse_start->first ;
158- double xh = x;
159- double yl = m_mouse_start->second ;
160- double yh = y;
161-
162- if (xl > xh){
163- std::swap (xl, xh);
164- }
165- if (yl > yh){
166- std::swap (yl, yh);
167- }
168-
169- program.X .set (xl);
170- program.Y .set (yl);
171- program.WIDTH .set (xh - xl);
172- program.HEIGHT .set (yh - yl);
173- }
174-
175- void DrawnBoundingBox::detach (){
176- auto & program = m_widget.m_program ;
177- m_overlay.remove_listener (*this );
178- program.X .remove_listener (*this );
179- program.Y .remove_listener (*this );
180- program.WIDTH .remove_listener (*this );
181- program.HEIGHT .remove_listener (*this );
182- }
183-
184112
185113LabelImages_Descriptor::LabelImages_Descriptor ()
186114 : PanelDescriptor(
@@ -444,10 +372,26 @@ void LabelImages::compute_embeddings_for_folder(const std::string& image_folder_
444372 ML::compute_embeddings_for_folder (embedding_model_path, image_folder_path);
445373}
446374
375+ void LabelImages::delete_last_annotation (){
376+ if (m_annotations.size () > 0 ){
377+ m_annotations.pop_back ();
378+ }
379+ if (m_annotations.size () > 0 ){
380+ m_last_object_idx = m_annotations.size () - 1 ;
381+ }
382+ }
447383
448384
449385LabelImages_Widget::~LabelImages_Widget (){
386+ m_program.X .remove_listener (*this );
387+ m_program.Y .remove_listener (*this );
388+ m_program.WIDTH .remove_listener (*this );
389+ m_program.HEIGHT .remove_listener (*this );
450390 m_program.FORM_LABEL .remove_listener (*this );
391+
392+ m_display_session.overlay ().remove_listener (*this );
393+ m_display_session.video_session ().remove_state_listener (*this );
394+
451395 delete m_image_display_widget;
452396}
453397LabelImages_Widget::LabelImages_Widget (
@@ -459,9 +403,14 @@ LabelImages_Widget::LabelImages_Widget(
459403 , m_program(program)
460404 , m_display_session(m_program.m_display_session)
461405 , m_overlay_set(m_display_session.overlay())
462- , m_drawn_box(*this , m_display_session.overlay())
463406{
407+ m_program.X .add_listener (*this );
408+ m_program.Y .add_listener (*this );
409+ m_program.WIDTH .add_listener (*this );
410+ m_program.HEIGHT .add_listener (*this );
464411 m_program.FORM_LABEL .add_listener (*this );
412+
413+ m_display_session.overlay ().add_listener (*this );
465414 m_display_session.video_session ().add_state_listener (*this );
466415
467416 m_embedding_info_label = new QLabel (this );
@@ -479,7 +428,7 @@ LabelImages_Widget::LabelImages_Widget(
479428 QVBoxLayout* scroll_layout = new QVBoxLayout (scroll_inner);
480429 scroll_layout->setAlignment (Qt::AlignTop);
481430
482- m_image_display_widget = new ImageAnnotationDisplayWidget (*this , m_display_session, 0 );
431+ m_image_display_widget = new ImageAnnotationDisplayWidget (*this , m_display_session, this );
483432 scroll_layout->addWidget (m_image_display_widget);
484433
485434 QHBoxLayout* embedding_info_row = new QHBoxLayout ();
@@ -491,12 +440,7 @@ LabelImages_Widget::LabelImages_Widget(
491440 scroll_layout->addWidget (button);
492441 connect (button, &QPushButton::clicked, this , [this ](bool ){
493442 auto & program = this ->m_program ;
494- if (program.m_annotations .size () > 0 ){
495- program.m_annotations .pop_back ();
496- }
497- if (program.m_annotations .size () > 0 ){
498- program.m_last_object_idx = program.m_annotations .size () - 1 ;
499- }
443+ program.delete_last_annotation ();
500444 program.update_rendered_objects (this ->m_overlay_set );
501445 });
502446
@@ -527,8 +471,8 @@ void LabelImages_Widget::on_config_value_changed(void* object){
527471 if (m_program.m_annotations .size () > 0 && m_program.m_last_object_idx < m_program.m_annotations .size ()){
528472 std::string& cur_label = m_program.m_annotations [m_program.m_last_object_idx ].label ;
529473 cur_label = m_program.FORM_LABEL .slug ();
530- m_program.update_rendered_objects (m_overlay_set);
531474 }
475+ m_program.update_rendered_objects (m_overlay_set);
532476}
533477
534478// This callback function will be called whenever the display source (the image source) is loaded or reloaded:
@@ -565,7 +509,56 @@ void LabelImages_Widget::post_startup(VideoSource* source){
565509 m_program.update_rendered_objects (m_overlay_set);
566510}
567511
512+ void LabelImages_Widget::key_release (QKeyEvent* event){
513+ const auto key = Qt::Key (event->key ());
514+ if (key == Qt::Key::Key_Delete || key == Qt::Key::Key_Backspace){
515+ m_program.delete_last_annotation ();
516+ m_program.update_rendered_objects (m_overlay_set);
517+ }
518+ }
519+
520+ void LabelImages_Widget::on_mouse_press (double x, double y){
521+ m_program.WIDTH .set (0 );
522+ m_program.HEIGHT .set (0 );
523+ m_program.X .set (x);
524+ m_program.Y .set (y);
525+ m_mouse_start.emplace ();
526+ m_mouse_end.emplace ();
527+ m_mouse_start->first = m_mouse_end->first = x;
528+ m_mouse_start->second = m_mouse_end->second = y;
529+ }
568530
531+ void LabelImages_Widget::on_mouse_release (double x, double y){
532+ m_mouse_start.reset ();
533+ m_mouse_end.reset ();
534+ m_program.compute_mask (m_overlay_set);
535+ }
536+
537+ void LabelImages_Widget::on_mouse_move (double x, double y){
538+ if (!m_mouse_start){
539+ return ;
540+ }
541+
542+ m_mouse_end->first = x;
543+ m_mouse_end->second = y;
544+
545+ double xl = m_mouse_start->first ;
546+ double yl = m_mouse_start->second ;
547+ double xh = x;
548+ double yh = y;
549+
550+ if (xl > xh){
551+ std::swap (xl, xh);
552+ }
553+ if (yl > yh){
554+ std::swap (yl, yh);
555+ }
556+
557+ m_program.X .set (xl);
558+ m_program.Y .set (yl);
559+ m_program.WIDTH .set (xh - xl);
560+ m_program.HEIGHT .set (yh - yl);
561+ }
569562
570563}
571564}
0 commit comments