From 4bc851544831e37b6173d0ad05806fd841e216fb Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Mon, 4 Nov 2024 20:42:36 -0500 Subject: Re-attempt 10 times, some tweaks to OCR, pre-filter card pool --- wizard.cpp | 243 ++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 137 insertions(+), 106 deletions(-) (limited to 'wizard.cpp') 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) { } Magick::Image wizard::run() { + tesseract_ptr api{new tesseract::TessBaseAPI()}; + + if (api->Init(nullptr, "eng", tesseract::OEM_TESSERACT_LSTM_COMBINED)) { + throw std::runtime_error("Could not initialize tesseract"); + } + + std::string allChars; + for (char ch : cards_.getCharacters()) { + allChars.push_back(ch); + if (std::isalpha(ch)) { + allChars.push_back(std::toupper(ch)); + } + } + + if (!api->SetVariable("tessedit_char_whitelist", allChars.c_str())) { + throw std::runtime_error("Could not set tesseract allowlist"); + } + std::string text = text_; //"what the heck, it's just some gay guy"; // getline(std::cin, text); if (text.back() == '\r') { @@ -68,104 +86,109 @@ Magick::Image wizard::run() { std::string canonText = hatkirby::lowercase(text); designer des(canonText, cards_.getTitles()); - std::list res = des.generate(rng_); Magick::Image endImage; - bool firstSlice = false; - int ui = 0; - - for (const usage& u : res) { - const card& theCard = cards_.getCard(u.cardId); - const std::string& cardName = theCard.name; - - std::cout << cardName.substr(0, u.strIndex) << "[" - << cardName.substr(u.strIndex, u.strLen) << "]" - << cardName.substr(u.strIndex + u.strLen) << std::endl; - - std::cout << "Downloading image..." << std::endl; - if (status_callback_) { - status_callback_("Downloading image..."); - } - - Magick::Image cardImg = images_.get(theCard.uuid, theCard.imageUri); - - std::cout << "Reading text..." << std::endl; - if (status_callback_) { - status_callback_("Reading text..."); - } - - Magick::Image titleImg = cardImg; - titleImg.magick("TIFF"); - - // titleImg.threshold(MaxRGB / 2); - titleImg.write("pre.tif"); - - Magick::Geometry margin; - - if (theCard.frame == card_frame::m2015) { - margin = Magick::Geometry{595, 46, 57, 54}; - } else if (theCard.frame == card_frame::modern) { - margin = Magick::Geometry{581, 50, 63, 57}; - } - - titleImg.crop(margin); - titleImg.zoom({margin.width() * 5, margin.height() * 5}); - - // titleImg.quantizeColorSpace(Magick::GRAYColorspace); - // titleImg.quantizeColors(2); - // titleImg.quantize(); - titleImg.backgroundColor("white"); - titleImg.matte(false); - titleImg.resolutionUnits(Magick::PixelsPerInchResolution); - titleImg.density({300, 300}); - titleImg.type(Magick::GrayscaleType); + bool success = false; + for (int attempt = 0; attempt < 10; attempt++) { + endImage = {}; + + std::list res = des.generate(rng_); + + bool firstSlice = false; + int ui = 0; + + bool failure = false; + for (const usage& u : res) { + const card& theCard = cards_.getCard(u.cardId); + const std::string& cardName = theCard.name; + + std::cout << cardName.substr(0, u.strIndex) << "[" + << cardName.substr(u.strIndex, u.strLen) << "]" + << cardName.substr(u.strIndex + u.strLen) << std::endl; + + std::cout << "Downloading image..." << std::endl; + if (status_callback_) { + std::ostringstream status_stream; + status_stream << "Processing card " << (ui + 1) << "/" << res.size() + << " (attempt " << (attempt + 1) << ")..."; + status_callback_(status_stream.str()); + } - titleImg.write("title.tif"); + Magick::Image cardImg = images_.get(theCard.uuid, theCard.imageUri); - Magick::Blob titleBlob; - titleImg.write(&titleBlob); + std::cout << "Reading text..." << std::endl; - pix_ptr titlePix{ - pixReadMemTiff(reinterpret_cast(titleBlob.data()), - titleBlob.length(), 0)}; + Magick::Image titleImg = cardImg; + titleImg.magick("TIFF"); - tesseract_ptr api{new tesseract::TessBaseAPI()}; + // titleImg.threshold(MaxRGB / 2); + titleImg.write("pre.tif"); - if (api->Init(nullptr, "eng")) { - throw std::runtime_error("Could not initialize tesseract"); - } + Magick::Geometry margin; - api->SetImage(titlePix.get()); - api->Recognize(nullptr); + if (theCard.frame == card_frame::m2015) { + margin = Magick::Geometry{595, 50, 57, 54}; + } else if (theCard.frame == card_frame::modern) { + margin = Magick::Geometry{581, 50, 63, 57}; + } - tesseract::ResultIterator* ri = api->GetIterator(); - tesseract::PageIteratorLevel level = tesseract::RIL_TEXTLINE; - bool foundName = false; - size_t extraChars = 0; + titleImg.crop(margin); + titleImg.zoom({margin.width() * 5, margin.height() * 5}); + + // titleImg.quantizeColorSpace(Magick::GRAYColorspace); + // titleImg.quantizeColors(2); + // titleImg.quantize(); + titleImg.backgroundColor("white"); + titleImg.matte(false); + titleImg.resolutionUnits(Magick::PixelsPerInchResolution); + titleImg.density({300, 300}); + titleImg.type(Magick::GrayscaleType); + titleImg.gamma(3); + // titleImg.level(0.2, 0.8); + + titleImg.write("title.tif"); + + Magick::Blob titleBlob; + titleImg.write(&titleBlob); + + pix_ptr titlePix{pixReadMemTiff( + reinterpret_cast(titleBlob.data()), + titleBlob.length(), 0)}; + + api->SetImage(titlePix.get()); + api->Recognize(nullptr); + + tesseract::ResultIterator* ri = api->GetIterator(); + tesseract::PageIteratorLevel level = tesseract::RIL_TEXTLINE; + bool foundName = false; + size_t extraChars = 0; + + if (ri) { + do { + const char* line = ri->GetUTF8Text(level); + + if (line) { + std::string lineStr(line); + + size_t leadin = hatkirby::lowercase(lineStr).find( + hatkirby::lowercase((cardName))); + if (leadin != std::string::npos) { + foundName = true; + extraChars = leadin; + + break; + } /* else { + std::cout << "WRONG: " << lineStr << std::endl; + }*/ + } + } while (ri->Next(level)); + } - if (ri) { - do { - const char* line = ri->GetUTF8Text(level); - - if (line) { - std::string lineStr(line); - - size_t leadin = hatkirby::lowercase(lineStr).find( - hatkirby::lowercase((cardName))); - // if (leadin != std::string::npos) - { - foundName = true; - // extraChars = leadin; - - break; - } /* else { - std::cout << "WRONG: " << lineStr << std::endl; - }*/ - } - } while (ri->Next(level)); - } + if (!foundName) { + failure = true; + break; + } - if (foundName) { level = tesseract::RIL_SYMBOL; for (int i = 0; i < extraChars; i++) { @@ -233,32 +256,40 @@ Magick::Image wizard::run() { cardImg.magick("PNG"); cardImg.write("slice.png"); - } else { - std::cout << "Didn't find name" << std::endl; - } - if (!firstSlice) { - firstSlice = true; - endImage = cardImg; + if (!firstSlice) { + firstSlice = true; + endImage = cardImg; - if (theCard.frame == card_frame::m2015) { - // endImage.extent({endImage.columns(), endImage.rows() + 6}, - // Magick::SouthGravity); - } - } else { - int xoff = endImage.columns(); + if (theCard.frame == card_frame::m2015) { + // endImage.extent({endImage.columns(), endImage.rows() + 6}, + // Magick::SouthGravity); + } + } else { + int xoff = endImage.columns(); - endImage.backgroundColor("black"); + endImage.backgroundColor("black"); - endImage.extent({endImage.columns() + cardImg.columns(), cardImg.rows()}, - Magick::WestGravity); + endImage.extent( + {endImage.columns() + cardImg.columns(), cardImg.rows()}, + Magick::WestGravity); - endImage.composite(cardImg, xoff, - (theCard.frame == card_frame::m2015) ? 6 : 0); + endImage.composite(cardImg, xoff, + (theCard.frame == card_frame::m2015) ? 6 : 0); + } + + // break; + ui++; } - // break; - ui++; + if (!failure) { + success = true; + break; + } + } + + if (!success) { + throw std::domain_error("Could not generate card"); } endImage.magick("PNG"); -- cgit 1.4.1