Skip to content

Commit ac73676

Browse files
author
Gin
committed
add forgotten new files
1 parent 3307436 commit ac73676

File tree

2 files changed

+225
-0
lines changed

2 files changed

+225
-0
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/* ML Label Images Overlay Manager
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
* Manages image overlay rendering for program LabelImages.
6+
*/
7+
8+
#include "Pokemon/Resources/Pokemon_PokemonForms.h"
9+
#include "ML_LabelImagesOverlayManager.h"
10+
#include "ML_LabelImages.h"
11+
12+
#include <iostream>
13+
using std::cout, std::endl;
14+
15+
16+
namespace PokemonAutomation{
17+
namespace ML{
18+
19+
inline size_t size_t_diff(size_t x, size_t y){
20+
return x >= y ? x - y : y - x;
21+
}
22+
inline size_t size_t_subtract_clamp(size_t x, size_t y){
23+
// max(x - y, 0)
24+
return x >= y ? x - y : 0;
25+
}
26+
27+
LabelImages_OverlayManager::LabelImages_OverlayManager(LabelImages& program)
28+
: m_program(program)
29+
, m_overlay_set(program.m_display_session.overlay())
30+
{
31+
m_inclusion_point_icon_template = ImageRGB32(21, 21);
32+
m_inclusion_point_icon_template.fill(0);
33+
const size_t strip_size = 5, strip_start = (21 - 5) / 2;
34+
for(size_t y = 0; y < strip_size; y++){
35+
for(size_t x = 0; x < m_inclusion_point_icon_template.width(); x++){
36+
m_inclusion_point_icon_template.pixel(x, y+strip_start) = uint32_t(COLOR_RED);
37+
}
38+
}
39+
for(size_t y = 0; y < m_inclusion_point_icon_template.height(); y++){
40+
for(size_t x = 0; x < strip_size; x++){
41+
m_inclusion_point_icon_template.pixel(x+strip_start, y) = uint32_t(COLOR_RED);
42+
}
43+
}
44+
45+
m_exclusion_point_icon_template = ImageRGB32(21, 21);
46+
m_exclusion_point_icon_template.fill(0);
47+
const size_t center = m_exclusion_point_icon_template.height() / 2;
48+
const size_t d2_min_th = (center-2)*(center-2);
49+
const size_t d2_max_th = (center+2)*(center+2);
50+
for(size_t y = 0; y < m_exclusion_point_icon_template.height(); y++){
51+
for(size_t x = 0; x < m_exclusion_point_icon_template.width(); x++){
52+
const size_t dx = size_t_diff(center, x);
53+
const size_t dy = size_t_diff(center, y);
54+
const size_t d2 = dx*dx + dy*dy;
55+
if (d2 >= d2_min_th && d2 <= d2_max_th){
56+
// double offset = std::fabs(std::sqrt(d2) - (double)center); // 0-3
57+
// int color_magnitude = int(255.0 * (1.0 - std::max(0.0, offset-2)) + 0.5);
58+
// color_magnitude = std::max(std::min(color_magnitude, 255), 0);
59+
// uint32_t color = combine_argb(uint8_t(color_magnitude), 0, 0, uint8_t(color_magnitude));
60+
// cout << x << " " << y << " " << offset << " " << color_magnitude << endl;
61+
m_exclusion_point_icon_template.pixel(x, y) = combine_argb(255, 0, 0, 200); // dark blue
62+
}
63+
}
64+
}
65+
66+
// m_inclusion_point_icon_template.save("./inclusion.png");
67+
// m_exclusion_point_icon_template.save("./exclusion.png");
68+
}
69+
70+
void LabelImages_OverlayManager::clear(){
71+
m_overlay_set.clear();
72+
73+
m_inclusion_point_icon = ImageRGB32();
74+
m_exclusion_point_icon = ImageRGB32();
75+
}
76+
77+
void LabelImages_OverlayManager::set_image_size(){
78+
const size_t point_icon_size = std::max(size_t(9), std::min(m_program.source_image_height, m_program.source_image_width) / 100);
79+
80+
m_inclusion_point_icon = m_inclusion_point_icon_template.scale_to(point_icon_size, point_icon_size);
81+
m_exclusion_point_icon = m_exclusion_point_icon_template.scale_to(point_icon_size, point_icon_size);
82+
}
83+
84+
85+
void LabelImages_OverlayManager::update_rendered_annotations(){
86+
m_overlay_set.clear();
87+
const size_t image_width = m_program.source_image_width;
88+
const size_t image_height = m_program.source_image_height;
89+
if (image_width <= 1 || image_height <= 1){
90+
return;
91+
}
92+
if (m_program.WIDTH > 0.0 && m_program.HEIGHT > 0.0){
93+
m_overlay_set.add(COLOR_RED, {m_program.X, m_program.Y, m_program.WIDTH, m_program.HEIGHT});
94+
}
95+
96+
const auto& annotations = m_program.m_annotations;
97+
const size_t& m_selected = m_program.m_selected_obj_idx;
98+
99+
auto create_overlay_for_index = [&](size_t i_obj){
100+
const auto& obj = annotations[i_obj];
101+
// overlayset.add(COLOR_RED, pixelbox_to_floatbox(source_image_width, source_image_height, obj.user_box));
102+
const auto mask_float_box = pixelbox_to_floatbox(image_width, image_height, obj.mask_box);
103+
std::string label = obj.label;
104+
const Pokemon::PokemonForm* form = Pokemon::get_pokemon_form(label);
105+
if (form != nullptr){
106+
label = form->display_name();
107+
}
108+
Color mask_box_color = (i_obj == m_selected) ? COLOR_BLACK : COLOR_BLUE;
109+
m_overlay_set.add(mask_box_color, mask_float_box, label);
110+
size_t mask_width = obj.mask_box.width();
111+
size_t mask_height = obj.mask_box.height();
112+
ImageRGB32 mask_image(mask_width, mask_height);
113+
// cout << "in render, mask_box " << obj.mask_box.min_x << " " << obj.mask_box.min_y << " " << obj.mask_box.max_x << " " << obj.mask_box.max_y << endl;
114+
115+
for (size_t y = 0; y < mask_height; y++){
116+
for (size_t x = 0; x < mask_width; x++){
117+
const bool mask = obj.mask[y*mask_width + x];
118+
uint32_t& pixel = mask_image.pixel(x, y);
119+
// if the pixel's mask value is true, set a semi-transparent 45-degree blue strip color
120+
// otherwise: fully transparent (alpha = 0)
121+
uint32_t color = 0;
122+
if (mask){
123+
color = (std::abs(int(x) - int(y)) % 4 <= 1) ? combine_argb(150, 30, 144, 255) : combine_argb(150, 0, 0, 60);
124+
}
125+
pixel = color;
126+
}
127+
}
128+
// cout << " count " << count << endl;
129+
m_overlay_set.add(std::move(mask_image), mask_float_box);
130+
131+
if (i_obj == m_selected){
132+
const size_t icon_size = m_inclusion_point_icon.height();
133+
const size_t icon_min_offset = icon_size / 2;
134+
const size_t icon_max_offset = icon_size - icon_min_offset;
135+
auto create_box = [&](const std::pair<size_t, size_t>& p) -> ImageFloatBox{
136+
size_t x_min = size_t_subtract_clamp(p.first, icon_min_offset);
137+
size_t x_max = std::min(p.first + icon_max_offset, image_width-1);
138+
size_t y_min = size_t_subtract_clamp(p.second, icon_min_offset);
139+
size_t y_max = std::min(p.second + icon_max_offset, image_height-1);
140+
ImagePixelBox box(x_min, y_min, x_max, y_max);
141+
return pixelbox_to_floatbox(image_width, image_height, box);
142+
};
143+
// the inclusion and exclusion points are only rendered for the current selected object:
144+
for(const auto& p : obj.inclusion_points){
145+
m_overlay_set.add(m_inclusion_point_icon.copy(), create_box(p));
146+
}
147+
for(const auto& p : obj.exclusion_points){
148+
m_overlay_set.add(m_exclusion_point_icon.copy(), create_box(p));
149+
}
150+
}
151+
};
152+
for(size_t i_obj = 0; i_obj < annotations.size(); i_obj++){
153+
if (i_obj == m_selected){
154+
// skip current selected annotation because we want to render it last so that
155+
// it will not be occluded by other annotations
156+
continue;
157+
}
158+
create_overlay_for_index(i_obj);
159+
}
160+
if (m_selected < annotations.size()){
161+
create_overlay_for_index(m_selected);
162+
}
163+
}
164+
165+
166+
}
167+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/* ML Label Images Overlay Manager
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
* Manages image overlay rendering for program LabelImages.
6+
* Since ML_LabelImages.cpp is quite long, moved the overlay rendering code
7+
* to this separate file.
8+
*/
9+
10+
#ifndef PokemonAutomation_ML_LabelImagesOverlayManager_H
11+
#define PokemonAutomation_ML_LabelImagesOverlayManager_H
12+
13+
14+
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
15+
#include "CommonFramework/ImageTypes/ImageRGB32.h"
16+
17+
18+
namespace PokemonAutomation{
19+
namespace ML{
20+
21+
class LabelImages;
22+
23+
24+
class LabelImages_OverlayManager{
25+
public:
26+
LabelImages_OverlayManager(LabelImages& proram);
27+
28+
// clear all data to prepare for a new image to label
29+
void clear();
30+
31+
// Initialize internal data related to source image size.
32+
// This must be called after LabelImages::source_image_width and source_image_height has been
33+
// set to the new size.
34+
// This must be called after clear() and before update_rendered_annotations().
35+
void set_image_size();
36+
37+
// called whenever a change in annotation data happens to update the corresponding
38+
// rendering data
39+
void update_rendered_annotations();
40+
41+
private:
42+
LabelImages& m_program;
43+
44+
VideoOverlaySet m_overlay_set;
45+
46+
ImageRGB32 m_inclusion_point_icon_template;
47+
ImageRGB32 m_exclusion_point_icon_template;
48+
49+
ImageRGB32 m_inclusion_point_icon;
50+
ImageRGB32 m_exclusion_point_icon;
51+
};
52+
53+
54+
}
55+
}
56+
57+
58+
#endif

0 commit comments

Comments
 (0)