Skip to content

Commit a176349

Browse files
committed
read_number_waterfill() with multiple filters
1 parent ec4b9d9 commit a176349

File tree

2 files changed

+89
-3
lines changed

2 files changed

+89
-3
lines changed

SerialPrograms/Source/CommonTools/OCR/OCR_NumberReader.cpp

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
#include "OCR_RawOCR.h"
1818
#include "OCR_NumberReader.h"
1919

20-
// #include <iostream>
21-
// using std::cout;
22-
// using std::endl;
20+
#include <iostream>
21+
using std::cout;
22+
using std::endl;
2323

2424
namespace PokemonAutomation{
2525
namespace OCR{
@@ -152,6 +152,82 @@ int read_number_waterfill(
152152
return number;
153153
}
154154

155+
int read_number_waterfill(
156+
Logger& logger, const ImageViewRGB32& image,
157+
std::vector<std::pair<uint32_t, uint32_t>> filters,
158+
uint32_t width_max,
159+
bool text_inside_range
160+
){
161+
using namespace Kernels::Waterfill;
162+
163+
164+
165+
for (std::pair<uint32_t, uint32_t> filter : filters){
166+
167+
uint32_t rgb32_min = filter.first;
168+
uint32_t rgb32_max = filter.second;
169+
170+
// Direct OCR is unreliable. Instead, we will waterfill each character
171+
// to isolate them, then OCR them individually.
172+
173+
ImageRGB32 filtered = to_blackwhite_rgb32_range(image, rgb32_min, rgb32_max, text_inside_range);
174+
175+
// static int c = 0;
176+
// static int i = 0;
177+
// filtered.save("test-" + std::to_string(c++) + ".png");
178+
179+
PackedBinaryMatrix matrix = compress_rgb32_to_binary_range(filtered, 0xff000000, 0xff7f7f7f);
180+
181+
std::map<size_t, WaterfillObject> map;
182+
{
183+
std::unique_ptr<WaterfillSession> session = make_WaterfillSession(matrix);
184+
auto iter = session->make_iterator(20);
185+
WaterfillObject object;
186+
bool exceed_width_max = false;
187+
while (map.size() < 16 && iter->find_next(object, true)){
188+
if (object.width() > width_max){
189+
exceed_width_max = true;
190+
break;
191+
}
192+
map.emplace(object.min_x, std::move(object));
193+
}
194+
if (exceed_width_max){
195+
// try the next color filter
196+
continue;
197+
}
198+
}
199+
200+
std::string ocr_text;
201+
for (const auto& item : map){
202+
const WaterfillObject& object = item.second;
203+
ImageRGB32 cropped = extract_box_reference(filtered, object).copy();
204+
PackedBinaryMatrix tmp(object.packed_matrix());
205+
filter_by_mask(tmp, cropped, Color(0xffffffff), true);
206+
ImageRGB32 padded = pad_image(cropped, cropped.width(), 0xffffffff);
207+
std::string ocr = OCR::ocr_read(Language::English, padded);
208+
// padded.save("test-cropped" + std::to_string(c) + "-" + std::to_string(i++) + ".png");
209+
// std::cout << ocr << std::endl;
210+
if (!ocr.empty()){
211+
ocr_text += ocr[0];
212+
}
213+
}
214+
215+
std::string normalized = run_number_normalization(ocr_text);
216+
217+
if (normalized.empty()){
218+
logger.log("OCR Text: \"" + ocr_text + "\" -> \"" + normalized + "\" -> Unable to read.", COLOR_RED);
219+
return -1;
220+
}
221+
222+
int number = std::atoi(normalized.c_str());
223+
logger.log("OCR Text: \"" + ocr_text + "\" -> \"" + normalized + "\" -> " + std::to_string(number));
224+
225+
return number;
226+
}
227+
228+
return -1;
229+
}
230+
155231

156232

157233

SerialPrograms/Source/CommonTools/OCR/OCR_NumberReader.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define PokemonAutomation_CommonTools_OCR_NumberReader_H
99

1010
#include <stdint.h>
11+
#include <vector>
1112
#include "CommonFramework/Language.h"
1213

1314
namespace PokemonAutomation{
@@ -32,6 +33,15 @@ int read_number_waterfill(
3233
bool text_inside_range = true
3334
);
3435

36+
// applies color filters on the text, until each individual waterfilled character/number is less than width_max. then apply OCR.
37+
// this solves the problem where characters are too close to each other and touch, causing more than one character to be OCR'ed
38+
// the filters should be arranged in order of preference. (probably should be arranged broadest to narrowest)
39+
int read_number_waterfill(
40+
Logger& logger, const ImageViewRGB32& image,
41+
std::vector<std::pair<uint32_t, uint32_t>> filters,
42+
uint32_t width_max,
43+
bool text_inside_range = true
44+
);
3545

3646

3747
}

0 commit comments

Comments
 (0)