Skip to content

Commit e5ef7bf

Browse files
author
Gin
committed
add custom labels
1 parent 40c6c0a commit e5ef7bf

File tree

4 files changed

+81
-2
lines changed

4 files changed

+81
-2
lines changed

SerialPrograms/Source/CommonTools/Options/StringSelectOption.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "Common/Cpp/Exceptions.h"
1313
#include "Common/Cpp/Containers/Pimpl.tpp"
1414
#include "Common/Cpp/Json/JsonValue.h"
15+
#include "Common/Cpp/Json/JsonArray.h"
1516
#include "StringSelectOption.h"
1617

1718
//#include <iostream>
@@ -106,6 +107,31 @@ void StringSelectDatabase::add_entry(StringSelectEntry entry){
106107
m_data->add_entry(std::move(entry));
107108
}
108109

110+
StringSelectDatabase create_string_select_database(const std::vector<std::string>& slugs){
111+
StringSelectDatabase database;
112+
for (const std::string& slug : slugs){
113+
// slug name is also the display name
114+
database.add_entry(StringSelectEntry(slug, slug));
115+
}
116+
return database;
117+
}
118+
119+
bool load_json_to_string_select_database(const JsonValue& json, StringSelectDatabase& database){
120+
const JsonArray* json_array = json.to_array();
121+
std::vector<std::string> slugs;
122+
if (json_array == nullptr){
123+
return false;
124+
}
125+
for (const JsonValue& element : *json_array){
126+
const std::string* str = element.to_string();
127+
if (str == nullptr){
128+
return false;
129+
}
130+
slugs.push_back(*str);
131+
}
132+
database = create_string_select_database(slugs);
133+
return true;
134+
}
109135

110136

111137

SerialPrograms/Source/CommonTools/Options/StringSelectOption.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
namespace PokemonAutomation{
1717

18+
class JsonValue;
1819

1920

2021

@@ -64,6 +65,15 @@ class StringSelectDatabase{
6465
Pimpl<Data> m_data;
6566
};
6667

68+
// Create a simple StringSelectDatabase from a list of slugs.
69+
// The display names of each entry will be the same as their slugs.
70+
StringSelectDatabase create_string_select_database(const std::vector<std::string>& slugs);
71+
// Load a simple list of JSON strings to a StringSelectDatabase.
72+
// Previous content of the StringSelectDatabase is removed if loading is successful.
73+
// The display names of each loaded entry will be the same as their slugs.
74+
// Return whether we successfully loaded from the JSON. If loading failed, the initial content
75+
// of the database is not removed.
76+
bool load_json_to_string_select_database(const JsonValue& json, StringSelectDatabase& database);
6777

6878
// Config option that creates a cell where users can select a string from
6979
// its dropdown menu. It is best to put this cell in a table widget.

SerialPrograms/Source/ML/Programs/ML_LabelImages.cpp

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include <QFileDialog>
88
#include <QLabel>
99
#include <QDir>
10+
#include <QGroupBox>
11+
#include <QRadioButton>
1012
#include <cfloat>
1113
#include <QDirIterator>
1214
#include <QVBoxLayout>
@@ -29,6 +31,7 @@
2931
#include "Common/Cpp/Json/JsonValue.h"
3032
#include "Common/Cpp/Json/JsonTools.h"
3133
#include "Common/Qt/CollapsibleGroupBox.h"
34+
#include "Pokemon/Pokemon_Strings.h"
3235
#include "Pokemon/Resources/Pokemon_PokemonForms.h"
3336
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
3437
#include "ML/UI/ML_ImageAnnotationDisplayWidget.h"
@@ -134,12 +137,18 @@ LabelImages::LabelImages(const LabelImages_Descriptor& descriptor)
134137
, WIDTH("<b>Width:</b>", LockMode::UNLOCK_WHILE_RUNNING, 0.4, 0.0, 1.0)
135138
, HEIGHT("<b>Height:</b>", LockMode::UNLOCK_WHILE_RUNNING, 0.4, 0.0, 1.0)
136139
, FORM_LABEL("bulbasaur")
140+
, CUSTOM_LABEL_DATABASE(create_string_select_database({
141+
"sun",
142+
"mc"
143+
}))
144+
, CUSTOM_LABEL(CUSTOM_LABEL_DATABASE, LockMode::UNLOCK_WHILE_RUNNING, 0)
137145
{
138146
ADD_OPTION(X);
139147
ADD_OPTION(Y);
140148
ADD_OPTION(WIDTH);
141149
ADD_OPTION(HEIGHT);
142150
ADD_OPTION(FORM_LABEL);
151+
ADD_OPTION(CUSTOM_LABEL);
143152

144153
// , m_sam_session{RESOURCE_PATH() + "ML/sam_cpu.onnx"}
145154
const std::string sam_model_path = RESOURCE_PATH() + "ML/sam_cpu.onnx";
@@ -529,12 +538,35 @@ LabelImages_Widget::LabelImages_Widget(
529538
button_row->addWidget(next_anno_button, 1);
530539

531540
// add a row for user annotation
541+
// the user can annotate in two modes:
542+
// - set a pokemon form label
543+
// - load a predefined custom string list and select from the list
544+
// The custom list cannot contain pokemon form name. Otherwise it will be set to the pokemon form label
545+
// so underlying data is only a single string. The UI reflects on what dropdown menu is set.
546+
// the UI needs to have a
532547
QHBoxLayout* annotation_row = new QHBoxLayout();
533548
scroll_layout->addLayout(annotation_row);
549+
534550
annotation_row->addWidget(new QLabel("<b>Select Label:</b>", scroll_inner), 0);
535551

536-
ConfigWidget* option_widget = program.FORM_LABEL.make_QtWidget(*scroll_inner);
537-
annotation_row->addWidget(&option_widget->widget(), 5);
552+
// add a group box for user to pick whether to choose from pokemon form label or custom label
553+
QGroupBox* label_type_group = new QGroupBox();
554+
QRadioButton* pokemon_radio_button = new QRadioButton(QString::fromStdString(Pokemon::STRING_POKEMON + " Forms"));
555+
QRadioButton* custom_label_radio_button = new QRadioButton("Custom Set");
556+
pokemon_radio_button->setChecked(true);
557+
558+
QHBoxLayout* group_box_layout = new QHBoxLayout;
559+
group_box_layout->addWidget(pokemon_radio_button);
560+
group_box_layout->addWidget(custom_label_radio_button);
561+
label_type_group->setLayout(group_box_layout);
562+
annotation_row->addWidget(label_type_group);
563+
564+
ConfigWidget* pokemon_label_widget = program.FORM_LABEL.make_QtWidget(*scroll_inner);
565+
annotation_row->addWidget(&pokemon_label_widget->widget(), 2);
566+
ConfigWidget* custom_label_widget = program.CUSTOM_LABEL.make_QtWidget(*scroll_inner);
567+
annotation_row->addWidget(&custom_label_widget->widget(), 2);
568+
// disable the custom label widget to correpsond to the default selection of label_type_group
569+
custom_label_widget->widget().setEnabled(false);
538570

539571
// add compute embedding button
540572

@@ -558,6 +590,15 @@ LabelImages_Widget::LabelImages_Widget(
558590
program.update_rendered_objects(this->m_overlay_set);
559591
});
560592

593+
connect(pokemon_radio_button, &QPushButton::clicked, this, [pokemon_label_widget, custom_label_widget](bool){
594+
pokemon_label_widget->widget().setEnabled(true);
595+
custom_label_widget->widget().setEnabled(false);
596+
});
597+
connect(custom_label_radio_button, &QPushButton::clicked, this, [pokemon_label_widget, custom_label_widget](bool){
598+
pokemon_label_widget->widget().setEnabled(false);
599+
custom_label_widget->widget().setEnabled(true);
600+
});
601+
561602
connect(compute_embedding_button, &QPushButton::clicked, this, [this](bool){
562603
std::string folder_path = QFileDialog::getExistingDirectory(
563604
nullptr, "Open image folder", ".").toStdString();

SerialPrograms/Source/ML/Programs/ML_LabelImages.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ class LabelImages : public PanelInstance{
119119
FloatingPointOption WIDTH;
120120
FloatingPointOption HEIGHT;
121121
Pokemon::HomeSpriteSelectCell FORM_LABEL;
122+
StringSelectDatabase CUSTOM_LABEL_DATABASE;
123+
StringSelectCell CUSTOM_LABEL;
122124

123125
size_t source_image_height = 0;
124126
size_t source_image_width = 0;

0 commit comments

Comments
 (0)