Skip to content

Commit 8106938

Browse files
author
Gin
committed
move more logic from widget to program
1 parent 2c745b8 commit 8106938

File tree

2 files changed

+47
-48
lines changed

2 files changed

+47
-48
lines changed

SerialPrograms/Source/ML/Programs/ML_LabelImages.cpp

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ IntegerEnumDropdownDatabase create_label_type_database(){
138138
LabelImages::LabelImages(const LabelImages_Descriptor& descriptor)
139139
: PanelInstance(descriptor)
140140
, m_display_session(m_display_option)
141+
, m_overlay_set(m_display_session.overlay())
141142
, m_options(LockMode::UNLOCK_WHILE_RUNNING)
142143
, X("<b>X Coordinate:</b>", LockMode::UNLOCK_WHILE_RUNNING, 0.3, 0.0, 1.0)
143144
, Y("<b>Y Coordinate:</b>", LockMode::UNLOCK_WHILE_RUNNING, 0.3, 0.0, 1.0)
@@ -160,7 +161,13 @@ LabelImages::LabelImages(const LabelImages_Descriptor& descriptor)
160161
ADD_OPTION(FORM_LABEL);
161162
ADD_OPTION(CUSTOM_LABEL);
162163

164+
X.add_listener(*this);
165+
Y.add_listener(*this);
166+
WIDTH.add_listener(*this);
167+
HEIGHT.add_listener(*this);
163168
LABEL_TYPE.add_listener(*this);
169+
FORM_LABEL.add_listener(*this);
170+
CUSTOM_LABEL.add_listener(*this);
164171

165172
// , m_sam_session{RESOURCE_PATH() + "ML/sam_cpu.onnx"}
166173
const std::string sam_model_path = RESOURCE_PATH() + "ML/sam_cpu.onnx";
@@ -173,6 +180,14 @@ LabelImages::LabelImages(const LabelImages_Descriptor& descriptor)
173180
QString::fromStdString("SAM model path" + sam_model_path + " does not exist."));
174181
}
175182
}
183+
LabelImages::~LabelImages(){
184+
X.remove_listener(*this);
185+
Y.remove_listener(*this);
186+
WIDTH.remove_listener(*this);
187+
HEIGHT.remove_listener(*this);
188+
LABEL_TYPE.remove_listener(*this);
189+
FORM_LABEL.remove_listener(*this);
190+
}
176191

177192
void LabelImages::from_json(const JsonValue& json){
178193
const JsonObject* obj = json.to_object();
@@ -206,6 +221,7 @@ void LabelImages::save_annotation_to_file() const{
206221
}
207222

208223
void LabelImages::clear_for_new_image(){
224+
m_overlay_set.clear();
209225
source_image_width = source_image_height = 0;
210226
m_image_embedding.clear();
211227
m_output_boolean_mask.clear();
@@ -220,6 +236,7 @@ QWidget* LabelImages::make_widget(QWidget& parent, PanelHolder& holder){
220236
return new LabelImages_Widget(parent, *this, holder);
221237
}
222238

239+
// assuming clear_for_new_image() is already called
223240
void LabelImages::load_image_related_data(const std::string& image_path, size_t source_image_width, size_t source_image_height){
224241
this->source_image_height = source_image_height;
225242
this->source_image_width = source_image_width;
@@ -277,13 +294,14 @@ void LabelImages::load_image_related_data(const std::string& image_path, size_t
277294
);
278295
}
279296
}
280-
m_selected_obj_idx = m_annotations.size();
297+
m_selected_obj_idx = m_annotations.size();
298+
update_rendered_objects();
281299
cout << "Loaded existing annotation file " << m_annotation_file_path << endl;
282300
}
283301

284-
void LabelImages::update_rendered_objects(VideoOverlaySet& overlay_set){
285-
overlay_set.clear();
286-
overlay_set.add(COLOR_RED, {X, Y, WIDTH, HEIGHT});
302+
void LabelImages::update_rendered_objects(){
303+
m_overlay_set.clear();
304+
m_overlay_set.add(COLOR_RED, {X, Y, WIDTH, HEIGHT});
287305

288306
for(size_t i_obj = 0; i_obj < m_annotations.size(); i_obj++){
289307
const auto& obj = m_annotations[i_obj];
@@ -295,7 +313,7 @@ void LabelImages::update_rendered_objects(VideoOverlaySet& overlay_set){
295313
label = form->display_name();
296314
}
297315
Color mask_box_color = (i_obj == m_selected_obj_idx) ? COLOR_BLACK : COLOR_BLUE;
298-
overlay_set.add(mask_box_color, mask_float_box, label);
316+
m_overlay_set.add(mask_box_color, mask_float_box, label);
299317
size_t mask_width = obj.mask_box.width();
300318
size_t mask_height = obj.mask_box.height();
301319
ImageRGB32 mask_image(mask_width, mask_height);
@@ -315,11 +333,11 @@ void LabelImages::update_rendered_objects(VideoOverlaySet& overlay_set){
315333
}
316334
}
317335
// cout << " count " << count << endl;
318-
overlay_set.add(std::move(mask_image), mask_float_box);
336+
m_overlay_set.add(std::move(mask_image), mask_float_box);
319337
}
320338
}
321339

322-
void LabelImages::compute_mask(VideoOverlaySet& overlay_set){
340+
void LabelImages::compute_mask(){
323341
const size_t source_width = source_image_width;
324342
const size_t source_height = source_image_height;
325343

@@ -384,7 +402,7 @@ void LabelImages::compute_mask(VideoOverlaySet& overlay_set){
384402
m_selected_obj_idx = m_annotations.size();
385403
m_annotations.emplace_back(std::move(annotation));
386404

387-
update_rendered_objects(overlay_set);
405+
update_rendered_objects();
388406
}
389407
}
390408

@@ -403,6 +421,7 @@ void LabelImages::delete_selected_annotation(){
403421

404422
if (m_annotations.size() == 0){
405423
m_selected_obj_idx = 0;
424+
update_rendered_objects();
406425
return;
407426
}
408427

@@ -414,6 +433,7 @@ void LabelImages::delete_selected_annotation(){
414433

415434
std::string& cur_label = m_annotations[m_selected_obj_idx].label;
416435
FORM_LABEL.set_by_slug(cur_label);
436+
update_rendered_objects();
417437
}
418438

419439
void LabelImages::change_annotation_selection_by_mouse(double x, double y){
@@ -458,6 +478,7 @@ void LabelImages::select_prev_annotation(){
458478
if (FORM_LABEL.slug() != new_label){
459479
FORM_LABEL.set_by_slug(new_label);
460480
}
481+
update_rendered_objects();
461482
}
462483
void LabelImages::select_next_annotation(){
463484
// no image or no annotation
@@ -477,6 +498,7 @@ void LabelImages::select_next_annotation(){
477498
if (FORM_LABEL.slug() != new_label){
478499
FORM_LABEL.set_by_slug(new_label);
479500
}
501+
update_rendered_objects();
480502
}
481503

482504
void LabelImages::on_config_value_changed(void* object){
@@ -490,16 +512,21 @@ void LabelImages::on_config_value_changed(void* object){
490512
CUSTOM_LABEL.set_visibility(ConfigOptionState::ENABLED);
491513
}
492514
}
515+
516+
if (object == &FORM_LABEL || object == &CUSTOM_LABEL || object == &LABEL_TYPE){
517+
if (m_annotations.size() > 0 && m_selected_obj_idx < m_annotations.size()){
518+
std::string& cur_label = m_annotations[m_selected_obj_idx].label;
519+
const std::string& ui_slug = FORM_LABEL.slug();
520+
if (ui_slug != cur_label){
521+
cur_label = FORM_LABEL.slug();
522+
}
523+
}
524+
update_rendered_objects();
525+
}
493526
}
494527

495528

496529
LabelImages_Widget::~LabelImages_Widget(){
497-
m_program.X.remove_listener(*this);
498-
m_program.Y.remove_listener(*this);
499-
m_program.WIDTH.remove_listener(*this);
500-
m_program.HEIGHT.remove_listener(*this);
501-
m_program.FORM_LABEL.remove_listener(*this);
502-
503530
m_display_session.overlay().remove_listener(*this);
504531
m_display_session.video_session().remove_state_listener(*this);
505532

@@ -513,14 +540,7 @@ LabelImages_Widget::LabelImages_Widget(
513540
: PanelWidget(parent, program, holder)
514541
, m_program(program)
515542
, m_display_session(m_program.m_display_session)
516-
, m_overlay_set(m_display_session.overlay())
517543
{
518-
m_program.X.add_listener(*this);
519-
m_program.Y.add_listener(*this);
520-
m_program.WIDTH.add_listener(*this);
521-
m_program.HEIGHT.add_listener(*this);
522-
m_program.FORM_LABEL.add_listener(*this);
523-
524544
m_display_session.overlay().add_listener(*this);
525545
m_display_session.video_session().add_state_listener(*this);
526546

@@ -590,18 +610,15 @@ LabelImages_Widget::LabelImages_Widget(
590610
connect(delete_anno_button, &QPushButton::clicked, this, [this](bool){
591611
auto& program = this->m_program;
592612
program.delete_selected_annotation();
593-
program.update_rendered_objects(this->m_overlay_set);
594613
});
595614

596615
connect(pre_anno_button, &QPushButton::clicked, this, [this](bool){
597616
auto& program = this->m_program;
598617
program.select_prev_annotation();
599-
program.update_rendered_objects(this->m_overlay_set);
600618
});
601619
connect(next_anno_button, &QPushButton::clicked, this, [this](bool){
602620
auto& program = this->m_program;
603621
program.select_next_annotation();
604-
program.update_rendered_objects(this->m_overlay_set);
605622
});
606623

607624
connect(compute_embedding_button, &QPushButton::clicked, this, [this](bool){
@@ -616,29 +633,16 @@ LabelImages_Widget::LabelImages_Widget(
616633
cout << "LabelImages_Widget built" << endl;
617634
}
618635

619-
void LabelImages_Widget::clear_for_new_image(){
620-
m_overlay_set.clear();
621-
m_program.clear_for_new_image();
622-
}
623636

624637
void LabelImages_Widget::on_config_value_changed(void* object){
625-
// TODO: the logic here should be part of LabelImage program
626-
if (m_program.m_annotations.size() > 0 && m_program.m_selected_obj_idx < m_program.m_annotations.size()){
627-
std::string& cur_label = m_program.m_annotations[m_program.m_selected_obj_idx].label;
628-
const std::string& ui_slug = m_program.FORM_LABEL.slug();
629-
if (ui_slug != cur_label){
630-
cur_label = m_program.FORM_LABEL.slug();
631-
}
632-
}
633-
m_program.update_rendered_objects(m_overlay_set);
634638
}
635639

636640
// This callback function will be called whenever the display source (the image source) is loaded or reloaded:
637641
void LabelImages_Widget::post_startup(VideoSource* source){
638642
const std::string& image_path = m_display_session.option().m_image_path;
639643

640644
m_program.save_annotation_to_file(); // save the current annotation file
641-
clear_for_new_image();
645+
m_program.clear_for_new_image();
642646
if (image_path.size() == 0){
643647
m_embedding_info_label->setText("");
644648
return;
@@ -664,14 +668,12 @@ void LabelImages_Widget::post_startup(VideoSource* source){
664668
}
665669

666670
m_program.load_image_related_data(image_path, cur_res.width, cur_res.height);
667-
m_program.update_rendered_objects(m_overlay_set);
668671
}
669672

670673
void LabelImages_Widget::key_release(QKeyEvent* event){
671674
const auto key = Qt::Key(event->key());
672675
if (key == Qt::Key::Key_Delete || key == Qt::Key::Key_Backspace){
673676
m_program.delete_selected_annotation();
674-
m_program.update_rendered_objects(m_overlay_set);
675677
}
676678
}
677679

@@ -695,7 +697,7 @@ void LabelImages_Widget::on_mouse_release(double x, double y){
695697
}
696698
m_mouse_start.reset();
697699
m_mouse_end.reset();
698-
m_program.compute_mask(m_overlay_set);
700+
m_program.compute_mask();
699701
}
700702

701703
void LabelImages_Widget::on_mouse_move(double x, double y){

SerialPrograms/Source/ML/Programs/ML_LabelImages.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class LabelImages : public PanelInstance, public ConfigOption::Listener {
7272
public:
7373
LabelImages(const LabelImages_Descriptor& descriptor);
7474
virtual QWidget* make_widget(QWidget& parent, PanelHolder& holder) override;
75+
~LabelImages();
7576

7677
public:
7778
// Serialization
@@ -90,10 +91,10 @@ class LabelImages : public PanelInstance, public ConfigOption::Listener {
9091
void load_image_related_data(const std::string& image_path, const size_t source_image_width, const size_t source_image_height);
9192

9293
// Update rendering data reflect the current annotation
93-
void update_rendered_objects(VideoOverlaySet& overlayset);
94+
void update_rendered_objects();
9495

9596
// Use user currently drawn box to compute per-pixel masks on the image using SAM model
96-
void compute_mask(VideoOverlaySet& overlay_set);
97+
void compute_mask();
9798

9899
// Compute embeddings for all images in a folder.
99100
// This can be very slow!
@@ -115,6 +116,7 @@ class LabelImages : public PanelInstance, public ConfigOption::Listener {
115116
ImageAnnotationDisplayOption m_display_option;
116117
// handles image display session, holding a reference to m_display_option
117118
ImageAnnotationDisplaySession m_display_session;
119+
VideoOverlaySet m_overlay_set;
118120
// the group option that holds rest of the options defined below:
119121
BatchOption m_options;
120122

@@ -164,9 +166,6 @@ class LabelImages_Widget : public PanelWidget,
164166
PanelHolder& holder
165167
);
166168

167-
// called after loading a new image, clean up all internal data
168-
void clear_for_new_image();
169-
170169
// Overwrites ConfigOption::Listener::on_config_value_changed().
171170
virtual void on_config_value_changed(void* object) override;
172171

@@ -194,8 +193,6 @@ class LabelImages_Widget : public PanelWidget,
194193
ImageAnnotationDisplaySession& m_display_session;
195194

196195
ImageAnnotationDisplayWidget* m_image_display_widget;
197-
198-
VideoOverlaySet m_overlay_set;
199196

200197
// show the info about the loaded image embedding data corresponding to the currently
201198
// displayed image

0 commit comments

Comments
 (0)