Skip to content

Commit eea87b9

Browse files
gzbykyasindavisking
authored andcommitted
Add undo and redo functionality to imglab (davisking#606) (davisking#3143)
Implemented Ctrl+Z and Ctrl+Y/Ctrl+Shift+Z shortcuts in imglab to undo and redo bounding box modifications. Added equality operators to box struct and limited maximum state history to 10 to avoid large memory footprints.
1 parent fcf5fbe commit eea87b9

3 files changed

Lines changed: 107 additions & 0 deletions

File tree

dlib/data_io/image_dataset_metadata.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,27 @@ namespace dlib
9393
ensures
9494
- returns true if label metadata is present and false otherwise.
9595
!*/
96+
97+
bool operator==(const box& rhs) const
98+
{
99+
return rect == rhs.rect &&
100+
parts == rhs.parts &&
101+
label == rhs.label &&
102+
difficult == rhs.difficult &&
103+
truncated == rhs.truncated &&
104+
occluded == rhs.occluded &&
105+
ignore == rhs.ignore &&
106+
pose == rhs.pose &&
107+
detection_score == rhs.detection_score &&
108+
angle == rhs.angle &&
109+
gender == rhs.gender &&
110+
age == rhs.age;
111+
}
112+
113+
bool operator!=(const box& rhs) const
114+
{
115+
return !(*this == rhs);
116+
}
96117
};
97118

98119
// ------------------------------------------------------------------------------------

tools/imglab/src/metadata_editor.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ extern const char* VERSION;
2121

2222
// ----------------------------------------------------------------------------------------
2323

24+
std::vector<dlib::image_display::overlay_rect> get_overlays (
25+
const dlib::image_dataset_metadata::image& data,
26+
color_mapper& string_to_color
27+
);
28+
2429
metadata_editor::
2530
metadata_editor(
2631
const std::string& filename_,
@@ -390,6 +395,25 @@ on_keydown (
390395
select_image(image_pos);
391396
}
392397

398+
if ((key == 'z' || key == 'Z') && (state&base_window::KBD_MOD_CONTROL) && !overlay_label.has_input_focus())
399+
{
400+
if (state&base_window::KBD_MOD_SHIFT)
401+
{
402+
perform_redo();
403+
}
404+
else
405+
{
406+
perform_undo();
407+
}
408+
return;
409+
}
410+
411+
if ((key == 'y' || key == 'Y') && (state&base_window::KBD_MOD_CONTROL) && !overlay_label.has_input_focus())
412+
{
413+
perform_redo();
414+
return;
415+
}
416+
393417
// Make 'w' and 's' act like KEY_UP and KEY_DOWN
394418
if ((key == 'w' || key == 'W') && !overlay_label.has_input_focus())
395419
{
@@ -532,6 +556,12 @@ load_image(
532556
if (idx >= metadata.images.size())
533557
return;
534558

559+
if (image_pos != idx)
560+
{
561+
undo_history.clear();
562+
redo_history.clear();
563+
}
564+
535565
image_pos = idx;
536566

537567
array2d<rgb_pixel> img;
@@ -556,6 +586,40 @@ load_image(
556586

557587
// ----------------------------------------------------------------------------------------
558588

589+
void metadata_editor::
590+
perform_undo()
591+
{
592+
if (!undo_history.empty())
593+
{
594+
redo_history.push_back(metadata.images[image_pos].boxes);
595+
if (redo_history.size() > MAX_UNDO_HISTORY) redo_history.erase(redo_history.begin());
596+
597+
metadata.images[image_pos].boxes = undo_history.back();
598+
undo_history.pop_back();
599+
display.clear_overlay();
600+
display.add_overlay(get_overlays(metadata.images[image_pos], string_to_color));
601+
}
602+
}
603+
604+
// ----------------------------------------------------------------------------------------
605+
606+
void metadata_editor::
607+
perform_redo()
608+
{
609+
if (!redo_history.empty())
610+
{
611+
undo_history.push_back(metadata.images[image_pos].boxes);
612+
if (undo_history.size() > MAX_UNDO_HISTORY) undo_history.erase(undo_history.begin());
613+
614+
metadata.images[image_pos].boxes = redo_history.back();
615+
redo_history.pop_back();
616+
display.clear_overlay();
617+
display.add_overlay(get_overlays(metadata.images[image_pos], string_to_color));
618+
}
619+
}
620+
621+
// ----------------------------------------------------------------------------------------
622+
559623
void metadata_editor::
560624
load_image_and_set_size(
561625
unsigned long idx
@@ -564,6 +628,12 @@ load_image_and_set_size(
564628
if (idx >= metadata.images.size())
565629
return;
566630

631+
if (image_pos != idx)
632+
{
633+
undo_history.clear();
634+
redo_history.clear();
635+
}
636+
567637
image_pos = idx;
568638

569639
array2d<rgb_pixel> img;
@@ -616,6 +686,7 @@ on_overlay_rects_changed(
616686
const std::vector<image_display::overlay_rect>& rects = display.get_overlay_rects();
617687

618688
std::vector<box>& boxes = metadata.images[image_pos].boxes;
689+
std::vector<box> old_boxes = boxes;
619690

620691
boxes.clear();
621692
for (unsigned long i = 0; i < rects.size(); ++i)
@@ -627,6 +698,14 @@ on_overlay_rects_changed(
627698
temp.ignore = rects[i].crossed_out;
628699
boxes.push_back(temp);
629700
}
701+
702+
if (old_boxes != boxes)
703+
{
704+
undo_history.push_back(old_boxes);
705+
if (undo_history.size() > MAX_UNDO_HISTORY)
706+
undo_history.erase(undo_history.begin());
707+
redo_history.clear();
708+
}
630709
}
631710
}
632711

tools/imglab/src/metadata_editor.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <dlib/data_io.h>
88
#include <dlib/pixel.h>
99
#include <map>
10+
#include <vector>
1011

1112
// ----------------------------------------------------------------------------------------
1213

@@ -69,6 +70,8 @@ class metadata_editor : public dlib::drawable_window
6970
);
7071

7172
private:
73+
void perform_undo();
74+
void perform_redo();
7275

7376
void file_save();
7477
void file_save_as();
@@ -96,6 +99,10 @@ class metadata_editor : public dlib::drawable_window
9699
std::string filename;
97100
dlib::image_dataset_metadata::dataset metadata;
98101

102+
std::vector<std::vector<dlib::image_dataset_metadata::box>> undo_history;
103+
std::vector<std::vector<dlib::image_dataset_metadata::box>> redo_history;
104+
static constexpr size_t MAX_UNDO_HISTORY = 10;
105+
99106
dlib::menu_bar mbar;
100107
dlib::list_box lb_images;
101108
unsigned long image_pos;

0 commit comments

Comments
 (0)