summary refs log tree commit diff stats
path: root/wizard.cpp
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2024-11-04 20:42:36 -0500
committerStar Rauchenberger <fefferburbia@gmail.com>2024-11-04 20:42:36 -0500
commit4bc851544831e37b6173d0ad05806fd841e216fb (patch)
treed6470fdb41fa6d9a87dd0a937c34d50af5529c35 /wizard.cpp
parentb5cc6373fbfe2db20bb14216242c2c56f9bfbafe (diff)
downloadwizard-main.tar.gz
wizard-main.tar.bz2
wizard-main.zip
Re-attempt 10 times, some tweaks to OCR, pre-filter card pool HEAD main
Diffstat (limited to 'wizard.cpp')
-rw-r--r--wizard.cpp243
1 files changed, 137 insertions, 106 deletions
diff --git a/wizard.cpp b/wizard.cpp index a1d7df4..c99ec79 100644 --- a/wizard.cpp +++ b/wizard.cpp
@@ -55,6 +55,24 @@ void wizard::set_status_callback(status_callback_type callback) {
55} 55}
56 56
57Magick::Image wizard::run() { 57Magick::Image wizard::run() {
58 tesseract_ptr api{new tesseract::TessBaseAPI()};
59
60 if (api->Init(nullptr, "eng", tesseract::OEM_TESSERACT_LSTM_COMBINED)) {
61 throw std::runtime_error("Could not initialize tesseract");
62 }
63
64 std::string allChars;
65 for (char ch : cards_.getCharacters()) {
66 allChars.push_back(ch);
67 if (std::isalpha(ch)) {
68 allChars.push_back(std::toupper(ch));
69 }
70 }
71
72 if (!api->SetVariable("tessedit_char_whitelist", allChars.c_str())) {
73 throw std::runtime_error("Could not set tesseract allowlist");
74 }
75
58 std::string text = text_; //"what the heck, it's just some gay guy"; 76 std::string text = text_; //"what the heck, it's just some gay guy";
59 // getline(std::cin, text); 77 // getline(std::cin, text);
60 if (text.back() == '\r') { 78 if (text.back() == '\r') {
@@ -68,104 +86,109 @@ Magick::Image wizard::run() {
68 86
69 std::string canonText = hatkirby::lowercase(text); 87 std::string canonText = hatkirby::lowercase(text);
70 designer des(canonText, cards_.getTitles()); 88 designer des(canonText, cards_.getTitles());
71 std::list<usage> res = des.generate(rng_);
72 89
73 Magick::Image endImage; 90 Magick::Image endImage;
74 bool firstSlice = false; 91 bool success = false;
75 int ui = 0; 92 for (int attempt = 0; attempt < 10; attempt++) {
76 93 endImage = {};
77 for (const usage& u : res) { 94
78 const card& theCard = cards_.getCard(u.cardId); 95 std::list<usage> res = des.generate(rng_);
79 const std::string& cardName = theCard.name; 96
80 97 bool firstSlice = false;
81 std::cout << cardName.substr(0, u.strIndex) << "[" 98 int ui = 0;
82 << cardName.substr(u.strIndex, u.strLen) << "]" 99
83 << cardName.substr(u.strIndex + u.strLen) << std::endl; 100 bool failure = false;
84 101 for (const usage& u : res) {
85 std::cout << "Downloading image..." << std::endl; 102 const card& theCard = cards_.getCard(u.cardId);
86 if (status_callback_) { 103 const std::string& cardName = theCard.name;
87 status_callback_("Downloading image..."); 104
88 } 105 std::cout << cardName.substr(0, u.strIndex) << "["
89 106 << cardName.substr(u.strIndex, u.strLen) << "]"
90 Magick::Image cardImg = images_.get(theCard.uuid, theCard.imageUri); 107 << cardName.substr(u.strIndex + u.strLen) << std::endl;
91 108
92 std::cout << "Reading text..." << std::endl; 109 std::cout << "Downloading image..." << std::endl;
93 if (status_callback_) { 110 if (status_callback_) {
94 status_callback_("Reading text..."); 111 std::ostringstream status_stream;
95 } 112 status_stream << "Processing card " << (ui + 1) << "/" << res.size()
96 113 << " (attempt " << (attempt + 1) << ")...";
97 Magick::Image titleImg = cardImg; 114 status_callback_(status_stream.str());
98 titleImg.magick("TIFF"); 115 }
99
100 // titleImg.threshold(MaxRGB / 2);
101 titleImg.write("pre.tif");
102
103 Magick::Geometry margin;
104
105 if (theCard.frame == card_frame::m2015) {
106 margin = Magick::Geometry{595, 46, 57, 54};
107 } else if (theCard.frame == card_frame::modern) {
108 margin = Magick::Geometry{581, 50, 63, 57};
109 }
110
111 titleImg.crop(margin);
112 titleImg.zoom({margin.width() * 5, margin.height() * 5});
113
114 // titleImg.quantizeColorSpace(Magick::GRAYColorspace);
115 // titleImg.quantizeColors(2);
116 // titleImg.quantize();
117 titleImg.backgroundColor("white");
118 titleImg.matte(false);
119 titleImg.resolutionUnits(Magick::PixelsPerInchResolution);
120 titleImg.density({300, 300});
121 titleImg.type(Magick::GrayscaleType);
122 116
123 titleImg.write("title.tif"); 117 Magick::Image cardImg = images_.get(theCard.uuid, theCard.imageUri);
124 118
125 Magick::Blob titleBlob; 119 std::cout << "Reading text..." << std::endl;
126 titleImg.write(&titleBlob);
127 120
128 pix_ptr titlePix{ 121 Magick::Image titleImg = cardImg;
129 pixReadMemTiff(reinterpret_cast<const unsigned char*>(titleBlob.data()), 122 titleImg.magick("TIFF");
130 titleBlob.length(), 0)};
131 123
132 tesseract_ptr api{new tesseract::TessBaseAPI()}; 124 // titleImg.threshold(MaxRGB / 2);
125 titleImg.write("pre.tif");
133 126
134 if (api->Init(nullptr, "eng")) { 127 Magick::Geometry margin;
135 throw std::runtime_error("Could not initialize tesseract");
136 }
137 128
138 api->SetImage(titlePix.get()); 129 if (theCard.frame == card_frame::m2015) {
139 api->Recognize(nullptr); 130 margin = Magick::Geometry{595, 50, 57, 54};
131 } else if (theCard.frame == card_frame::modern) {
132 margin = Magick::Geometry{581, 50, 63, 57};
133 }
140 134
141 tesseract::ResultIterator* ri = api->GetIterator(); 135 titleImg.crop(margin);
142 tesseract::PageIteratorLevel level = tesseract::RIL_TEXTLINE; 136 titleImg.zoom({margin.width() * 5, margin.height() * 5});
143 bool foundName = false; 137
144 size_t extraChars = 0; 138 // titleImg.quantizeColorSpace(Magick::GRAYColorspace);
139 // titleImg.quantizeColors(2);
140 // titleImg.quantize();
141 titleImg.backgroundColor("white");
142 titleImg.matte(false);
143 titleImg.resolutionUnits(Magick::PixelsPerInchResolution);
144 titleImg.density({300, 300});
145 titleImg.type(Magick::GrayscaleType);
146 titleImg.gamma(3);
147 // titleImg.level(0.2, 0.8);
148
149 titleImg.write("title.tif");
150
151 Magick::Blob titleBlob;
152 titleImg.write(&titleBlob);
153
154 pix_ptr titlePix{pixReadMemTiff(
155 reinterpret_cast<const unsigned char*>(titleBlob.data()),
156 titleBlob.length(), 0)};
157
158 api->SetImage(titlePix.get());
159 api->Recognize(nullptr);
160
161 tesseract::ResultIterator* ri = api->GetIterator();
162 tesseract::PageIteratorLevel level = tesseract::RIL_TEXTLINE;
163 bool foundName = false;
164 size_t extraChars = 0;
165
166 if (ri) {
167 do {
168 const char* line = ri->GetUTF8Text(level);
169
170 if (line) {
171 std::string lineStr(line);
172
173 size_t leadin = hatkirby::lowercase(lineStr).find(
174 hatkirby::lowercase((cardName)));
175 if (leadin != std::string::npos) {
176 foundName = true;
177 extraChars = leadin;
178
179 break;
180 } /* else {
181 std::cout << "WRONG: " << lineStr << std::endl;
182 }*/
183 }
184 } while (ri->Next(level));
185 }
145 186
146 if (ri) { 187 if (!foundName) {
147 do { 188 failure = true;
148 const char* line = ri->GetUTF8Text(level); 189 break;
149 190 }
150 if (line) {
151 std::string lineStr(line);
152
153 size_t leadin = hatkirby::lowercase(lineStr).find(
154 hatkirby::lowercase((cardName)));
155 // if (leadin != std::string::npos)
156 {
157 foundName = true;
158 // extraChars = leadin;
159
160 break;
161 } /* else {
162 std::cout << "WRONG: " << lineStr << std::endl;
163 }*/
164 }
165 } while (ri->Next(level));
166 }
167 191
168 if (foundName) {
169 level = tesseract::RIL_SYMBOL; 192 level = tesseract::RIL_SYMBOL;
170 193
171 for (int i = 0; i < extraChars; i++) { 194 for (int i = 0; i < extraChars; i++) {
@@ -233,32 +256,40 @@ Magick::Image wizard::run() {
233 256
234 cardImg.magick("PNG"); 257 cardImg.magick("PNG");
235 cardImg.write("slice.png"); 258 cardImg.write("slice.png");
236 } else {
237 std::cout << "Didn't find name" << std::endl;
238 }
239 259
240 if (!firstSlice) { 260 if (!firstSlice) {
241 firstSlice = true; 261 firstSlice = true;
242 endImage = cardImg; 262 endImage = cardImg;
243 263
244 if (theCard.frame == card_frame::m2015) { 264 if (theCard.frame == card_frame::m2015) {
245 // endImage.extent({endImage.columns(), endImage.rows() + 6}, 265 // endImage.extent({endImage.columns(), endImage.rows() + 6},
246 // Magick::SouthGravity); 266 // Magick::SouthGravity);
247 } 267 }
248 } else { 268 } else {
249 int xoff = endImage.columns(); 269 int xoff = endImage.columns();
250 270
251 endImage.backgroundColor("black"); 271 endImage.backgroundColor("black");
252 272
253 endImage.extent({endImage.columns() + cardImg.columns(), cardImg.rows()}, 273 endImage.extent(
254 Magick::WestGravity); 274 {endImage.columns() + cardImg.columns(), cardImg.rows()},
275 Magick::WestGravity);
255 276
256 endImage.composite(cardImg, xoff, 277 endImage.composite(cardImg, xoff,
257 (theCard.frame == card_frame::m2015) ? 6 : 0); 278 (theCard.frame == card_frame::m2015) ? 6 : 0);
279 }
280
281 // break;
282 ui++;
258 } 283 }
259 284
260 // break; 285 if (!failure) {
261 ui++; 286 success = true;
287 break;
288 }
289 }
290
291 if (!success) {
292 throw std::domain_error("Could not generate card");
262 } 293 }
263 294
264 endImage.magick("PNG"); 295 endImage.magick("PNG");