Skip to content

Commit b2d69c8

Browse files
committed
Improve reliability of TeraCard pokemon detection.
1 parent 9f809a6 commit b2d69c8

File tree

2 files changed

+69
-24
lines changed

2 files changed

+69
-24
lines changed

SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,12 +268,22 @@ void TestProgram::program(MultiSwitchProgramEnvironment& env, CancellableScope&
268268

269269

270270

271-
ImageRGB32 image("20250126-022538815397.png");
272-
MaxLairInternal::BattleMenuReader reader(overlay, Language::Korean);
273-
reader.read_opponent_in_summary(logger, image);
271+
ImageRGB32 image("20250125-232444699636.png");
274272

273+
TeraSilhouetteReader reader;
274+
ImageMatch::ImageMatchResult results = reader.read(image);
275+
results.log(logger, 110);
275276

276277

278+
279+
#if 0
280+
ImageRGB32 image("20250125-224044294692.png");
281+
MaxLairInternal::BattleMenuReader reader(overlay, Language::English);
282+
std::set<std::string> slugs = reader.read_opponent_in_summary(logger, image);
283+
284+
cout << set_to_str(slugs) << endl;
285+
#endif
286+
277287
// ssf_press_button(context, BUTTON_A, 0, 1000, 0);
278288
// pbf_move_left_joystick(context, 0, 0, 20, 0);
279289

SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraSilhouetteReader.cpp

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55
*/
66

77
#include <opencv2/imgproc.hpp>
8+
#include "CommonFramework/Logging/Logger.h"
89
#include "CommonTools/Images/ImageFilter.h"
910
#include "CommonTools/ImageMatch/ImageCropper.h"
1011
#include "PokemonSV/Resources/PokemonSV_PokemonSprites.h"
1112
#include "PokemonSV_TeraSilhouetteReader.h"
1213

14+
//#include <iostream>
15+
//using std::cout;
16+
//using std::endl;
17+
1318
namespace PokemonAutomation{
1419
namespace NintendoSwitch{
1520
namespace PokemonSV{
@@ -46,32 +51,62 @@ ImageMatch::ImageMatchResult TeraSilhouetteReader::read(const ImageViewRGB32& sc
4651
static constexpr double MAX_ALPHA = 110;
4752
static constexpr double ALPHA_SPREAD = 20;
4853

49-
// Get a loose crop of the silhouette icon
50-
ImageViewRGB32 cropped_image = extract_box_reference(screen, m_box);
51-
//cropped_image.save("cropped_image.png");
54+
const std::vector<uint32_t> BRIGHTNESS_THRESHOLDS{
55+
200,
56+
150,
57+
100,
58+
125,
59+
175,
60+
225,
61+
};
62+
63+
for (uint32_t threshold : BRIGHTNESS_THRESHOLDS){
64+
// cout << "check0" << endl;
65+
// Get a loose crop of the silhouette icon
66+
ImageViewRGB32 cropped_image = extract_box_reference(screen, m_box);
67+
// cropped_image.save("tera_cropped_image.png");
68+
69+
// cout << "check1" << endl;
70+
ImageRGB32 preprocessed_image(cropped_image.width(), cropped_image.height());
71+
cv::medianBlur(cropped_image.to_opencv_Mat(), preprocessed_image.to_opencv_Mat(), 5);
72+
// preprocessed_image.save("tera_blurred_image.png");
73+
74+
// Get a tight crop
75+
// cout << "check2" << endl;
76+
const ImagePixelBox tight_box = ImageMatch::enclosing_rectangle_with_pixel_filter(
77+
preprocessed_image,
78+
// The filter is a lambda function that returns true on black silhouette pixels.
79+
[=](Color pixel){
80+
// return (uint32_t)pixel.red() + pixel.green() + pixel.blue() < 200;
81+
return (uint32_t)pixel.red() + pixel.green() + pixel.blue() < threshold;
82+
}
83+
);
84+
85+
if (tight_box.area() == 0){
86+
global_logger_tagged().log("TeraSilhouetteReader::read(): Cropped image is empty.", COLOR_RED);
87+
return ImageMatch::ImageMatchResult();
88+
}
5289

53-
ImageRGB32 preprocessed_image(cropped_image.width(), cropped_image.height());
54-
cv::medianBlur(cropped_image.to_opencv_Mat(), preprocessed_image.to_opencv_Mat(), 5);
55-
//preprocessed_image.save("preprocessed_image.png");
90+
// cout << "check3" << endl;
91+
ImageRGB32 processed_image = extract_box_reference(preprocessed_image, tight_box).copy();
92+
// processed_image.save("tera_processed_image.png");
5693

57-
// Get a tight crop
58-
const ImagePixelBox tight_box = ImageMatch::enclosing_rectangle_with_pixel_filter(
59-
preprocessed_image,
60-
// The filter is a lambda function that returns true on black silhouette pixels.
61-
[](Color pixel){
62-
return (uint32_t)pixel.red() + pixel.green() + pixel.blue() < 200;
63-
}
64-
);
65-
ImageRGB32 processed_image = extract_box_reference(preprocessed_image, tight_box).copy();
66-
// processed_image.save("processed_image.png");
94+
// cout << "check4" << endl;
95+
ImageRGB32 filtered_image = to_blackwhite_rgb32_range(processed_image, 0xff000000, 0xff5f5f5f, true);
96+
// filtered_image.save("tera_filtered_image.png");
6797

68-
ImageRGB32 filtered_image = to_blackwhite_rgb32_range(processed_image, 0xff000000, 0xff5f5f5f, true);
69-
// filtered_image.save("filtered_image.png");
98+
// cout << "check5" << endl;
99+
ImageMatch::ImageMatchResult slugs = TERA_RAID_SILHOUETTE_MATCHER().match(filtered_image, ALPHA_SPREAD);
100+
slugs.clear_beyond_alpha(MAX_ALPHA);
70101

71-
ImageMatch::ImageMatchResult slugs = TERA_RAID_SILHOUETTE_MATCHER().match(filtered_image, ALPHA_SPREAD);
72-
slugs.clear_beyond_alpha(MAX_ALPHA);
102+
// slugs.log(global_logger_tagged(), MAX_ALPHA);
103+
104+
if (slugs.results.size() == 1){
105+
return slugs;
106+
}
107+
}
73108

74-
return slugs;
109+
return ImageMatch::ImageMatchResult();
75110
}
76111

77112

0 commit comments

Comments
 (0)