|
17 | 17 | #include "OCR_RawOCR.h" |
18 | 18 | #include "OCR_NumberReader.h" |
19 | 19 |
|
20 | | -// #include <iostream> |
21 | | -// using std::cout; |
22 | | -// using std::endl; |
| 20 | +#include <iostream> |
| 21 | +using std::cout; |
| 22 | +using std::endl; |
23 | 23 |
|
24 | 24 | namespace PokemonAutomation{ |
25 | 25 | namespace OCR{ |
@@ -152,6 +152,82 @@ int read_number_waterfill( |
152 | 152 | return number; |
153 | 153 | } |
154 | 154 |
|
| 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 | + |
155 | 231 |
|
156 | 232 |
|
157 | 233 |
|
|
0 commit comments