From 947ba357c1f2e283538c08edab14023aeb2ef41a Mon Sep 17 00:00:00 2001 From: jw098 Date: Tue, 23 Jun 2026 17:32:58 -0700 Subject: [PATCH 1/7] Refactor OCR toggle --- .../CommonTools/OCR/OCR_NumberReader.cpp | 19 ++------- .../Source/CommonTools/OCR/OCR_RawOCR.cpp | 6 +-- .../Source/CommonTools/OCR/OCR_RawOCR.h | 2 +- .../CommonTools/OCR/OCR_RawPaddleOCR.cpp | 15 ++++++- .../Source/CommonTools/OCR/OCR_Routines.cpp | 39 +++++++++++-------- .../Source/CommonTools/OCR/OCR_Routines.h | 1 + .../ML/Inference/ML_PaddleOCRPipeline.cpp | 4 +- .../ML/Inference/ML_PaddleOCRPipeline.h | 2 + .../DateManip/NintendoSwitch_DateManip_US.cpp | 2 +- .../Programs/PokemonHome_BoxNavigation.cpp | 1 - .../Inference/PokemonSV_MoneyReader.cpp | 2 +- .../Tera/PokemonSV_TeraCardDetector.cpp | 2 +- .../Tera/PokemonSV_TeraCodeReader.cpp | 2 +- .../PokemonSV_VideoFastCodeEntry.cpp | 2 +- .../PokemonSwSh_MaxLair_Detect_HPPP.cpp | 2 +- 15 files changed, 54 insertions(+), 47 deletions(-) diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_NumberReader.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_NumberReader.cpp index c51e593463..26f10da3f3 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_NumberReader.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_NumberReader.cpp @@ -18,8 +18,7 @@ #include "CommonTools/Images/ImageManip.h" #include "CommonTools/Images/ImageFilter.h" #include "CommonTools/Images/BinaryImage_FilterRgb32.h" -#include "OCR_RawOCR.h" -#include "OCR_RawPaddleOCR.h" +#include "OCR_Routines.h" #include "OCR_NumberReader.h" #include @@ -85,13 +84,7 @@ std::string run_number_normalization(const std::string& input){ int read_number(Logger& logger, const ImageViewRGB32& image, Language language){ - bool use_paddle_ocr = false; // GlobalSettings::instance().USE_PADDLE_OCR; - std::string ocr_text; - if (use_paddle_ocr){ - ocr_text = OCR::paddle_ocr_read(language, image); - }else{ - ocr_text = OCR::ocr_read(language, image, OCR::PageSegMode::SINGLE_LINE); - } + std::string ocr_text = OCR::ocr_read(language, image, OCR::PageSegMode::SINGLE_LINE); std::string normalized = run_number_normalization(ocr_text); @@ -179,13 +172,7 @@ std::string read_number_waterfill_no_normalization( } ImageRGB32 padded = pad_image(cropped, 1 * cropped.width(), 0xffffffff); - bool use_paddle_ocr = false; // GlobalSettings::instance().USE_PADDLE_OCR; - std::string ocr; - if (use_paddle_ocr){ - ocr = OCR::paddle_ocr_read(Language::English, padded); - }else{ - ocr = OCR::ocr_read(Language::English, padded, OCR::PageSegMode::SINGLE_CHAR); - } + std::string ocr = OCR::ocr_read(Language::English, padded, OCR::PageSegMode::SINGLE_CHAR); // padded.save("zztest-cropped" + std::to_string(c) + "-" + std::to_string(i++) + ".png"); // std::cout << ocr[0] << std::endl; diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.cpp index 592d0d8369..b07bbbd860 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.cpp @@ -179,7 +179,7 @@ struct OcrGlobals{ }; -std::string ocr_read(Language language, const ImageViewRGB32& image, PageSegMode psm){ +std::string tesseract_ocr_read(Language language, const ImageViewRGB32& image, PageSegMode psm){ // static size_t c = 0; // image.save("ocr-" + std::to_string(c++) + ".png"); @@ -193,7 +193,7 @@ std::string ocr_read(Language language, const ImageViewRGB32& image, PageSegMode // Get or create the pool for this language (lock only during map access). std::map::iterator iter; { - WriteSpinLock lg(globals.ocr_pool_lock, "ocr_read()"); + WriteSpinLock lg(globals.ocr_pool_lock, "tesseract_ocr_read()"); iter = ocr_pool.find(language); if (iter == ocr_pool.end()){ iter = ocr_pool.emplace(language, language).first; @@ -219,7 +219,7 @@ void ensure_instances(Language language, size_t instances){ // Get or create the pool for this language. std::map::iterator iter; { - WriteSpinLock lg(globals.ocr_pool_lock, "ocr_read()"); + WriteSpinLock lg(globals.ocr_pool_lock, "tesseract_ocr_read()"); iter = ocr_pool.find(language); if (iter == ocr_pool.end()){ iter = ocr_pool.emplace(language, language).first; diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h b/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h index e9c7ff6b92..815e5f9005 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h @@ -51,7 +51,7 @@ bool language_available(Language language); // // psm: Page segmentation mode - controls how Tesseract interprets the image layout. // Defaults to SINGLE_BLOCK (Tesseract C++ API's default) for best performance. -std::string ocr_read( +std::string tesseract_ocr_read( Language language, const ImageViewRGB32& image, PageSegMode psm = PageSegMode::SINGLE_BLOCK diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp index 055761ff64..ea645446bc 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp @@ -4,10 +4,14 @@ * */ -#include "ML/Inference/ML_PaddleOCRPipeline.h" +#include "Common/Cpp/Filesystem.h" +#include "CommonFramework/Globals.h" +#include "CommonFramework/Logging/Logger.h" +#include "CommonFramework/Exceptions/OperationFailedException.h" #include "Common/Cpp/Exceptions.h" #include "Common/Cpp/Concurrency/SpinLock.h" #include "CommonFramework/ImageTypes/ImageViewRGB32.h" +#include "ML/Inference/ML_PaddleOCRPipeline.h" #include "OCR_RawOCR.h" namespace PokemonAutomation{ @@ -94,6 +98,15 @@ std::string paddle_ocr_read(Language language, const ImageViewRGB32& image){ // static size_t c = 0; // image.save("ocr-" + std::to_string(c++) + ".png"); + std::string path = ML::PaddleOCRPipeline::get_paths(language).first; + Filesystem::Path p{path}; + if (!std::filesystem::exists(p)){ + Logger& logger = global_logger_tagged(); + throw_and_log(logger, ErrorReport::NO_ERROR_REPORT, + "Error: PaddleOCR file does not exist."); + } + + ML::PaddleOCRPipeline& paddle_instance = ensure_paddle_ocr_instance(language); // Run inference with the paddle model. diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp index 2361ba2520..2f841ad2de 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp @@ -7,15 +7,16 @@ #include "CommonFramework/ImageTypes/ImageRGB32.h" #include "CommonFramework/Tools/GlobalThreadPools.h" #include "CommonFramework/GlobalSettingsPanel.h" +#include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonTools/Images/ImageFilter.h" #include "OCR_RawPaddleOCR.h" #include "OCR_RawOCR.h" #include "OCR_DictionaryMatcher.h" #include "OCR_Routines.h" -// #include -// using std::cout; -// using std::endl; +#include +using std::cout; +using std::endl; @@ -23,6 +24,22 @@ namespace PokemonAutomation{ namespace OCR{ +std::string ocr_read(Language language, const ImageViewRGB32& image, PageSegMode psm){ + std::string ocr_text = ""; + if (GlobalSettings::instance().USE_PADDLE_OCR){ + try{ + ocr_text = OCR::paddle_ocr_read(language, image); + }catch(OperationFailedException&){ + cout << "Fall back to default OCR library." << endl; + ocr_text = OCR::tesseract_ocr_read(language, image, OCR::PageSegMode::SINGLE_LINE); + } + }else{ + ocr_text = OCR::tesseract_ocr_read(language, image, OCR::PageSegMode::SINGLE_LINE); + } + return ocr_text; +} + + StringMatchResult multifiltered_OCR( Language language, const DictionaryMatcher& dictionary, const ImageViewRGB32& image, const std::vector& text_color_ranges, @@ -44,8 +61,6 @@ StringMatchResult multifiltered_OCR( double pixels_inv = 1. / (image.width() * image.height()); - bool use_paddle_ocr = GlobalSettings::instance().USE_PADDLE_OCR; - // Run all the filters. SpinLock lock; StringMatchResult ret; @@ -53,12 +68,7 @@ StringMatchResult multifiltered_OCR( [&](size_t index){ const std::pair& filtered = filtered_images[index]; - std::string text; - if (use_paddle_ocr){ - text = paddle_ocr_read(language, filtered.first); - }else{ - text = ocr_read(language, filtered.first, psm); - } + std::string text = OCR::ocr_read(language, filtered.first, psm); // cout << "multifiltered_OCR: " << index << " -> " << text << endl; // filtered.first.save("test_" + std::to_string(index) + ".png"); @@ -110,12 +120,7 @@ StringMatchResult dictionary_OCR( } // Run all the filters. - std::string text; - if (GlobalSettings::instance().USE_PADDLE_OCR){ - text = paddle_ocr_read(language, image); - }else{ - text = ocr_read(language, image, psm); - } + std::string text = OCR::ocr_read(language, image, psm); // cout << "dictionary_OCR: " << text << endl; // image.save("test_dictionary_OCR.png"); diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h index e627577e18..1da7a41333 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h @@ -30,6 +30,7 @@ struct TextColorRange{ {} }; +std::string ocr_read(Language language, const ImageViewRGB32& image, PageSegMode psm = PageSegMode::SINGLE_LINE); // psm: Tesseract Page Segmentation mode. See // SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h:PageSegMode diff --git a/SerialPrograms/Source/ML/Inference/ML_PaddleOCRPipeline.cpp b/SerialPrograms/Source/ML/Inference/ML_PaddleOCRPipeline.cpp index 4b6037460f..1a29a8be37 100644 --- a/SerialPrograms/Source/ML/Inference/ML_PaddleOCRPipeline.cpp +++ b/SerialPrograms/Source/ML/Inference/ML_PaddleOCRPipeline.cpp @@ -19,8 +19,8 @@ namespace PokemonAutomation{ namespace ML{ -static std::pair get_paths(Language language){ - std::string base = RESOURCE_PATH() + "PaddleOCR/"; +std::pair PaddleOCRPipeline::get_paths(Language language){ + std::string base = DOWNLOADED_RESOURCE_PATH() + "PaddleOCR/"; switch(language){ case Language::None: throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Attempted to call OCR without a language."); diff --git a/SerialPrograms/Source/ML/Inference/ML_PaddleOCRPipeline.h b/SerialPrograms/Source/ML/Inference/ML_PaddleOCRPipeline.h index a04fdd8f12..9fe2bbbdf2 100644 --- a/SerialPrograms/Source/ML/Inference/ML_PaddleOCRPipeline.h +++ b/SerialPrograms/Source/ML/Inference/ML_PaddleOCRPipeline.h @@ -32,6 +32,8 @@ class PaddleOCRPipeline { std::string recognize(const ImageViewRGB32& image); + static std::pair get_paths(Language language); + private: void load_dictionary(const std::string& path); diff --git a/SerialPrograms/Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManip_US.cpp b/SerialPrograms/Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManip_US.cpp index 7190b491ed..408f9afdf3 100644 --- a/SerialPrograms/Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManip_US.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManip_US.cpp @@ -11,7 +11,7 @@ #include "CommonFramework/VideoPipeline/VideoFeed.h" #include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" #include "CommonFramework/Tools/VideoStream.h" -#include "CommonTools/OCR/OCR_RawOCR.h" +#include "CommonTools/OCR/OCR_Routines.h" #include "CommonTools/OCR/OCR_StringNormalization.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" #include "NintendoSwitch_DateManipTools.h" diff --git a/SerialPrograms/Source/PokemonHome/Programs/PokemonHome_BoxNavigation.cpp b/SerialPrograms/Source/PokemonHome/Programs/PokemonHome_BoxNavigation.cpp index 4eebbb79a6..95e1e97df4 100644 --- a/SerialPrograms/Source/PokemonHome/Programs/PokemonHome_BoxNavigation.cpp +++ b/SerialPrograms/Source/PokemonHome/Programs/PokemonHome_BoxNavigation.cpp @@ -14,7 +14,6 @@ #include "CommonFramework/ImageTools/ImageStats.h" #include "CommonFramework/Notifications/ProgramInfo.h" #include "CommonTools/Images/ImageFilter.h" -#include "CommonTools/OCR/OCR_RawOCR.h" #include "CommonTools/OCR/OCR_Routines.h" #include "CommonTools/OCR/OCR_StringNormalization.h" #include "CommonFramework/Tools/ErrorDumper.h" diff --git a/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_MoneyReader.cpp b/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_MoneyReader.cpp index d2c5e30b10..2411710731 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_MoneyReader.cpp +++ b/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_MoneyReader.cpp @@ -7,7 +7,7 @@ #include #include "Common/Cpp/Logging/AbstractLogger.h" #include "CommonFramework/Language.h" -#include "CommonTools/OCR/OCR_RawOCR.h" +#include "CommonTools/OCR/OCR_Routines.h" #include "PokemonSV_MoneyReader.h" //#include diff --git a/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.cpp b/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.cpp index 0521e8adcb..fca4f91158 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.cpp +++ b/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.cpp @@ -17,7 +17,7 @@ #include "CommonFramework/Tools/ErrorDumper.h" #include "CommonTools/Images/SolidColorTest.h" #include "CommonTools/Images/BinaryImage_FilterRgb32.h" -#include "CommonTools/OCR/OCR_RawOCR.h" +#include "CommonTools/OCR/OCR_Routines.h" #include "PokemonSV/Inference/Dialogs/PokemonSV_GradientArrowDetector.h" #include "PokemonSV_TeraCodeReader.h" #include "PokemonSV_TeraCardDetector.h" diff --git a/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCodeReader.cpp b/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCodeReader.cpp index aeac7c1095..f819715681 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCodeReader.cpp +++ b/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCodeReader.cpp @@ -15,7 +15,7 @@ #include "CommonTools/Images/ImageFilter.h" #include "CommonTools/Images/BinaryImage_FilterRgb32.h" #include "CommonTools/ImageMatch/ExactImageMatcher.h" -#include "CommonTools/OCR/OCR_RawOCR.h" +#include "CommonTools/OCR/OCR_Routines.h" #include "PokemonSV_TeraCodeReader.h" //#define PA_ENABLE_CODE_DEBUG diff --git a/SerialPrograms/Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_VideoFastCodeEntry.cpp b/SerialPrograms/Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_VideoFastCodeEntry.cpp index 4d97223525..dd867498dc 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_VideoFastCodeEntry.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_VideoFastCodeEntry.cpp @@ -10,7 +10,7 @@ #include "CommonFramework/Tools/GlobalThreadPools.h" #include "CommonFramework/VideoPipeline/VideoFeed.h" #include "CommonTools/Images/ImageFilter.h" -#include "CommonTools/OCR/OCR_RawOCR.h" +#include "CommonTools/OCR/OCR_Routines.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" #include "NintendoSwitch/Inference/NintendoSwitch_ConsoleTypeDetector.h" #include "Pokemon/Pokemon_Strings.h" diff --git a/SerialPrograms/Source/PokemonSwSh/MaxLair/Inference/PokemonSwSh_MaxLair_Detect_HPPP.cpp b/SerialPrograms/Source/PokemonSwSh/MaxLair/Inference/PokemonSwSh_MaxLair_Detect_HPPP.cpp index fc889c5cd3..72b501b149 100644 --- a/SerialPrograms/Source/PokemonSwSh/MaxLair/Inference/PokemonSwSh_MaxLair_Detect_HPPP.cpp +++ b/SerialPrograms/Source/PokemonSwSh/MaxLair/Inference/PokemonSwSh_MaxLair_Detect_HPPP.cpp @@ -10,7 +10,7 @@ #include "CommonTools/Images/ImageFilter.h" #include "CommonTools/Images/SolidColorTest.h" #include "CommonTools/OCR/OCR_StringNormalization.h" -#include "CommonTools/OCR/OCR_RawOCR.h" +#include "CommonTools/OCR/OCR_Routines.h" #include "Pokemon/Inference/Pokemon_ReadHpBar.h" #include "PokemonSwSh_MaxLair_Detect_HPPP.h" From 888e98eaf36952e47d30eb73f30c42e5d1e5d373 Mon Sep 17 00:00:00 2001 From: jw098 Date: Thu, 25 Jun 2026 22:39:06 -0700 Subject: [PATCH 2/7] disallow direct usage of Tesseract or PaddleOCR, and use OCR_Routines instead. --- .../Source/CommonFramework/Main.cpp | 4 +- .../Source/CommonTools/OCR/OCR_RawOCR.cpp | 6 +-- .../Source/CommonTools/OCR/OCR_RawOCR.h | 8 ++-- .../CommonTools/OCR/OCR_RawPaddleOCR.cpp | 15 +++---- .../Source/CommonTools/OCR/OCR_RawPaddleOCR.h | 2 + .../Source/CommonTools/OCR/OCR_Routines.cpp | 41 +++++++++++++++---- .../Source/CommonTools/OCR/OCR_Routines.h | 6 +++ .../CommonTools/Options/LanguageOCROption.cpp | 4 +- .../DevPrograms/TestProgramSwitch.cpp | 4 +- .../PokemonLZA_HyperspaceCalorieDetector.cpp | 4 +- .../PokemonSV_VideoFastCodeEntry.cpp | 2 +- 11 files changed, 64 insertions(+), 32 deletions(-) diff --git a/SerialPrograms/Source/CommonFramework/Main.cpp b/SerialPrograms/Source/CommonFramework/Main.cpp index da844b8fed..f5dfd09985 100644 --- a/SerialPrograms/Source/CommonFramework/Main.cpp +++ b/SerialPrograms/Source/CommonFramework/Main.cpp @@ -35,7 +35,7 @@ #include "Startup/SetupSettings.h" #include "Startup/NewVersionCheck.h" #include "CommonFramework/VideoPipeline/Backends/CameraImplementations.h" -#include "CommonTools/OCR/OCR_RawOCR.h" +#include "CommonTools/OCR/OCR_Routines.h" #include "ControllerInput/ControllerInput.h" #include "Controllers/SerialPortPollerQt.h" #include "Integrations/DiscordWebhook.h" @@ -225,7 +225,7 @@ int main(int argc, char *argv[]){ // We must clear the OCR cache or it will crash on Linux when the library // unloads before the cache is destructed from static memory. - OCR::clear_cache(); + OCR::clear_ocr_cache(); // Stop the controllers. global_input_stop(); diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.cpp index b07bbbd860..ab455bb89c 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.cpp @@ -24,7 +24,7 @@ namespace PokemonAutomation{ namespace OCR{ -bool language_available(Language language){ +bool tesseract_language_available(Language language){ std::string path = RESOURCE_PATH(); path += "Tesseract/"; path += language_data(language).code; @@ -208,7 +208,7 @@ std::string tesseract_ocr_read(Language language, const ImageViewRGB32& image, P } -void ensure_instances(Language language, size_t instances){ +void ensure_tesseract_instances(Language language, size_t instances){ if (language == Language::None){ throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Attempted to call OCR without a language."); } @@ -229,7 +229,7 @@ void ensure_instances(Language language, size_t instances){ iter->second.ensure_instances(instances); } -void clear_cache(){ +void clear_tesseract_cache(){ OcrGlobals& globals = OcrGlobals::instance(); std::map& ocr_pool = globals.ocr_pool; WriteSpinLock lg(globals.ocr_pool_lock, "ocr_clear_cache()"); diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h b/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h index 815e5f9005..6f648c1fc2 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h @@ -39,7 +39,7 @@ enum class PageSegMode : int { // Check if Tesseract training data exists for the given language. -bool language_available(Language language); +bool tesseract_language_available(Language language); // OCR the image in the specified language. @@ -47,7 +47,7 @@ bool language_available(Language language); // Thread-safe: internally uses a pool of Tesseract API instances, able to accept // multiple concurrent calls without delay or queueing. // It creates a new Tesseract instances if no available idle instance. You can -// call `ensure_instances()` to pre-warm to pool with a given number of instances. +// call `ensure_tesseract_instances()` to pre-warm to pool with a given number of instances. // // psm: Page segmentation mode - controls how Tesseract interprets the image layout. // Defaults to SINGLE_BLOCK (Tesseract C++ API's default) for best performance. @@ -63,12 +63,12 @@ std::string tesseract_ocr_read( // Avoids lazy initialization delays during runtime. Thread-safe. // Call this if you expect to need to do many OCR instances in parallel and you // want to preload the OCR instances. -void ensure_instances(Language language, size_t instances); +void ensure_tesseract_instances(Language language, size_t instances); // Clear all TesseractAPI instances for all languages. Used for cleanup or // forcing re-initialization. // This is not safe to call while in any OCR is still running! -void clear_cache(); +void clear_tesseract_cache(); diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp index ea645446bc..5578745574 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp @@ -7,7 +7,6 @@ #include "Common/Cpp/Filesystem.h" #include "CommonFramework/Globals.h" #include "CommonFramework/Logging/Logger.h" -#include "CommonFramework/Exceptions/OperationFailedException.h" #include "Common/Cpp/Exceptions.h" #include "Common/Cpp/Concurrency/SpinLock.h" #include "CommonFramework/ImageTypes/ImageViewRGB32.h" @@ -54,6 +53,12 @@ LanguageGroup language_to_languagegroup(Language language){ } } +bool paddle_ocr_language_available(Language language){ + std::string path = ML::PaddleOCRPipeline::get_paths(language).first; + Filesystem::Path p{path}; + return std::filesystem::exists(p); +} + // Global singleton managing the single PaddleOCR instance for each language. // ocr_pool_lock protects the map @@ -98,14 +103,6 @@ std::string paddle_ocr_read(Language language, const ImageViewRGB32& image){ // static size_t c = 0; // image.save("ocr-" + std::to_string(c++) + ".png"); - std::string path = ML::PaddleOCRPipeline::get_paths(language).first; - Filesystem::Path p{path}; - if (!std::filesystem::exists(p)){ - Logger& logger = global_logger_tagged(); - throw_and_log(logger, ErrorReport::NO_ERROR_REPORT, - "Error: PaddleOCR file does not exist."); - } - ML::PaddleOCRPipeline& paddle_instance = ensure_paddle_ocr_instance(language); diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.h b/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.h index 90cf5524c9..ba57d3f630 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.h @@ -17,6 +17,8 @@ namespace PokemonAutomation{ } namespace OCR{ +bool paddle_ocr_language_available(Language language); + // Pre-warm the PaddleOCR instance pool for a language. Ensure one instance exists. // Avoids lazy initialization delays during runtime. Thread-safe. diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp index 2f841ad2de..208f15ef30 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp @@ -23,22 +23,49 @@ using std::endl; namespace PokemonAutomation{ namespace OCR{ +// return true if the user enabled PaddleOCR and its resource has been downloaded +bool use_paddle_ocr(){ + static bool use_paddle_ocr = GlobalSettings::instance().USE_PADDLE_OCR && paddle_ocr_language_available(Language::English); + + return use_paddle_ocr; +} + +bool ocr_language_available(Language language){ + if (use_paddle_ocr()){ + return OCR::paddle_ocr_language_available(language); + }else{ + return OCR::tesseract_language_available(language); + } +} + std::string ocr_read(Language language, const ImageViewRGB32& image, PageSegMode psm){ std::string ocr_text = ""; - if (GlobalSettings::instance().USE_PADDLE_OCR){ - try{ - ocr_text = OCR::paddle_ocr_read(language, image); - }catch(OperationFailedException&){ - cout << "Fall back to default OCR library." << endl; - ocr_text = OCR::tesseract_ocr_read(language, image, OCR::PageSegMode::SINGLE_LINE); - } + if (use_paddle_ocr()){ + ocr_text = OCR::paddle_ocr_read(language, image); }else{ ocr_text = OCR::tesseract_ocr_read(language, image, OCR::PageSegMode::SINGLE_LINE); } return ocr_text; } +void ensure_ocr_instances(Language language, size_t instances){ + if (use_paddle_ocr()){ + OCR::ensure_paddle_ocr_instance(language); + }else{ + OCR::ensure_tesseract_instances(language, instances); + } +} + +void clear_ocr_cache(){ + if (use_paddle_ocr()){ + OCR::clear_paddle_ocr_cache(); + }else{ + OCR::clear_tesseract_cache(); + } +} + + StringMatchResult multifiltered_OCR( Language language, const DictionaryMatcher& dictionary, const ImageViewRGB32& image, diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h index 1da7a41333..d7236b12af 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h @@ -30,8 +30,14 @@ struct TextColorRange{ {} }; +bool ocr_language_available(Language language); + std::string ocr_read(Language language, const ImageViewRGB32& image, PageSegMode psm = PageSegMode::SINGLE_LINE); +void ensure_ocr_instances(Language language, size_t instances = 1); + +void clear_ocr_cache(); + // psm: Tesseract Page Segmentation mode. See // SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h:PageSegMode StringMatchResult multifiltered_OCR( diff --git a/SerialPrograms/Source/CommonTools/Options/LanguageOCROption.cpp b/SerialPrograms/Source/CommonTools/Options/LanguageOCROption.cpp index 3fb35887a6..38ba6bcba7 100644 --- a/SerialPrograms/Source/CommonTools/Options/LanguageOCROption.cpp +++ b/SerialPrograms/Source/CommonTools/Options/LanguageOCROption.cpp @@ -7,7 +7,7 @@ #include "Common/Cpp/Exceptions.h" #include "Common/Cpp/Json/JsonValue.h" #include "CommonFramework/Logging/Logger.h" -#include "CommonTools/OCR/OCR_RawOCR.h" +#include "CommonTools/OCR/OCR_Routines.h" #include "LanguageOCROption.h" //#include @@ -44,7 +44,7 @@ LanguageOCRCell::LanguageOCRCell( for (Language language : languages){ m_case_list.emplace_back( language, - language == Language::None || OCR::language_available(language) + language == Language::None || OCR::ocr_language_available(language) ); m_case_map.emplace( std::piecewise_construct, diff --git a/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp b/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp index ecbf48bed7..da23406d3f 100644 --- a/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp +++ b/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp @@ -170,7 +170,7 @@ #include "Common/PABotBase2/ReliableConnectionLayer/PABotBase2CC_ReliableStreamConnection.h" #include "Common/Cpp/StreamConnections/MockDevice.h" #include "ML/Inference/ML_PaddleOCRPipeline.h" -#include "CommonTools/OCR/OCR_RawPaddleOCR.h" +#include "CommonTools/OCR/OCR_Routines.h" #include "CommonTools/Images/ImageTools.h" #include "PokemonFRLG/Inference/PokemonFRLG_BattleSelectionArrowDetector.h" #include "Controllers/RumbleListener.h" @@ -671,7 +671,7 @@ void TestProgram::program(MultiSwitchProgramEnvironment& env, CancellableScope& ImageViewRGB32 cropped = extract_box_reference(image1, ImageFloatBox{BOX.x(), BOX.y(), BOX.width(), BOX.height()}); // auto snapshot = feed.snapshot(); - std::string text = OCR::paddle_ocr_read(LANGUAGE, cropped); + std::string text = OCR::ocr_read(LANGUAGE, cropped); cout << text << endl; diff --git a/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceCalorieDetector.cpp b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceCalorieDetector.cpp index d6a9178d9c..cdda4731ca 100644 --- a/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceCalorieDetector.cpp +++ b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceCalorieDetector.cpp @@ -10,7 +10,7 @@ #include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" #include "CommonFramework/Tools/GlobalThreadPools.h" #include "CommonTools/OCR/OCR_NumberReader.h" -#include "CommonTools/OCR/OCR_RawOCR.h" +#include "CommonTools/OCR/OCR_Routines.h" #include "PokemonLZA_HyperspaceCalorieDetector.h" namespace PokemonAutomation{ @@ -29,7 +29,7 @@ void HyperspaceCalorieDetector::make_overlays(VideoOverlaySet& items) const{ void HyperspaceCalorieDetector::warm_ocr(){ // Ensure the number used here matches the actual filter size used in detect() - OCR::ensure_instances(Language::English, 5); + OCR::ensure_ocr_instances(Language::English, 5); } bool HyperspaceCalorieDetector::detect(const ImageViewRGB32& screen){ diff --git a/SerialPrograms/Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_VideoFastCodeEntry.cpp b/SerialPrograms/Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_VideoFastCodeEntry.cpp index dd867498dc..b219f25419 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_VideoFastCodeEntry.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_VideoFastCodeEntry.cpp @@ -168,7 +168,7 @@ VideoFastCodeEntry::VideoFastCodeEntry() // Preload GlobalThreadPools::computation_realtime().ensure_threads(6); - OCR::ensure_instances(Language::English, 6); + OCR::ensure_ocr_instances(Language::English, 6); preload_code_templates(); } void VideoFastCodeEntry::update_active_consoles(size_t switch_count){ From 0b319411a5d1868e009892b76d1df6700cf162be Mon Sep 17 00:00:00 2001 From: jw098 Date: Thu, 25 Jun 2026 22:53:30 -0700 Subject: [PATCH 3/7] clean up headers --- SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp | 2 +- SerialPrograms/Source/CommonTools/OCR/OCR_TextMatcher.h | 1 - .../Source/NintendoSwitch/DevPrograms/TestProgramComputer.cpp | 1 - .../Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp | 2 -- .../Programs/DateManip/NintendoSwitch_DateManipTools.cpp | 1 - SerialPrograms/Source/Pokemon/Inference/Pokemon_NameReader.cpp | 1 - .../Source/Pokemon/Inference/Pokemon_PokeballNameReader.cpp | 1 - .../PokemonLZA/Inference/PokemonLZA_HyperspaceCalorieDetector.h | 2 +- .../Inference/PokemonLZA_HyperspaceRewardNameReader.cpp | 1 - .../PokemonPokopia/Inference/PokemonPokopia_PCDetection.cpp | 1 - .../Inference/ItemPrinter/PokemonSV_ItemPrinterPrizeReader.cpp | 1 - .../PokemonSV/Inference/PokemonSV_AuctionItemNameReader.cpp | 1 - .../PokemonSV/Inference/PokemonSV_TournamentPrizeNameReader.cpp | 1 - 13 files changed, 2 insertions(+), 14 deletions(-) diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp index 5578745574..14750d4d10 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp @@ -11,7 +11,7 @@ #include "Common/Cpp/Concurrency/SpinLock.h" #include "CommonFramework/ImageTypes/ImageViewRGB32.h" #include "ML/Inference/ML_PaddleOCRPipeline.h" -#include "OCR_RawOCR.h" +#include "OCR_RawPaddleOCR.h" namespace PokemonAutomation{ namespace OCR{ diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_TextMatcher.h b/SerialPrograms/Source/CommonTools/OCR/OCR_TextMatcher.h index 693f763396..424ed18683 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_TextMatcher.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_TextMatcher.h @@ -11,7 +11,6 @@ #include #include #include -#include "OCR_RawOCR.h" #include "OCR_StringMatchResult.h" namespace PokemonAutomation{ diff --git a/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramComputer.cpp b/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramComputer.cpp index 744235169f..b4d6fcf708 100644 --- a/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramComputer.cpp +++ b/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramComputer.cpp @@ -28,7 +28,6 @@ #include "CommonFramework/Exceptions/ProgramFinishedException.h" #include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonFramework/ImageTools/ImageBoxes.h" -#include "CommonTools/OCR/OCR_RawOCR.h" #include "CommonTools/OCR/OCR_Routines.h" #include "PokemonSV/Inference/Tera/PokemonSV_TeraCodeReader.h" #include "PokemonSwSh/MaxLair/Inference/PokemonSwSh_MaxLair_Detect_BattleMenu.h" diff --git a/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp b/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp index da23406d3f..b44779e4ad 100644 --- a/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp +++ b/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp @@ -15,7 +15,6 @@ #include "Common/Cpp/Concurrency/BusyPeriodicRunner.h" #include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonTools/Async/InferenceRoutines.h" -#include "CommonTools/OCR/OCR_RawOCR.h" #include "PokemonLA/Inference/PokemonLA_MountDetector.h" #include "Pokemon/Pokemon_Strings.h" #include "PokemonBDSP/Inference/BoxSystem/PokemonBDSP_IvJudgeReader.h" @@ -169,7 +168,6 @@ #include "Common/PABotBase2/ReliableConnectionLayer/PABotBase2FW_ReliableStreamConnection.h" #include "Common/PABotBase2/ReliableConnectionLayer/PABotBase2CC_ReliableStreamConnection.h" #include "Common/Cpp/StreamConnections/MockDevice.h" -#include "ML/Inference/ML_PaddleOCRPipeline.h" #include "CommonTools/OCR/OCR_Routines.h" #include "CommonTools/Images/ImageTools.h" #include "PokemonFRLG/Inference/PokemonFRLG_BattleSelectionArrowDetector.h" diff --git a/SerialPrograms/Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManipTools.cpp b/SerialPrograms/Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManipTools.cpp index e6f7706cbd..ce6be374a1 100644 --- a/SerialPrograms/Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManipTools.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManipTools.cpp @@ -7,7 +7,6 @@ #include "CommonFramework/ImageTypes/ImageRGB32.h" #include "CommonFramework/ImageTools/ImageStats.h" #include "CommonTools/Images/ImageFilter.h" -//#include "CommonTools/OCR/OCR_RawOCR.h" #include "CommonTools/OCR/OCR_NumberReader.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" #include "NintendoSwitch_DateManipTools.h" diff --git a/SerialPrograms/Source/Pokemon/Inference/Pokemon_NameReader.cpp b/SerialPrograms/Source/Pokemon/Inference/Pokemon_NameReader.cpp index f5b1b2b62b..1130b327c7 100644 --- a/SerialPrograms/Source/Pokemon/Inference/Pokemon_NameReader.cpp +++ b/SerialPrograms/Source/Pokemon/Inference/Pokemon_NameReader.cpp @@ -4,7 +4,6 @@ * */ -#include "CommonTools/OCR/OCR_RawOCR.h" #include "Pokemon_NameReader.h" namespace PokemonAutomation{ diff --git a/SerialPrograms/Source/Pokemon/Inference/Pokemon_PokeballNameReader.cpp b/SerialPrograms/Source/Pokemon/Inference/Pokemon_PokeballNameReader.cpp index 1f5a64b52c..9f0ef2ffa6 100644 --- a/SerialPrograms/Source/Pokemon/Inference/Pokemon_PokeballNameReader.cpp +++ b/SerialPrograms/Source/Pokemon/Inference/Pokemon_PokeballNameReader.cpp @@ -4,7 +4,6 @@ * */ -#include "CommonTools/OCR/OCR_RawOCR.h" #include "Pokemon_PokeballNameReader.h" namespace PokemonAutomation{ diff --git a/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceCalorieDetector.h b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceCalorieDetector.h index 409152471f..56439e23c9 100644 --- a/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceCalorieDetector.h +++ b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceCalorieDetector.h @@ -35,7 +35,7 @@ class HyperspaceCalorieDetector : public StaticScreenDetector{ uint16_t calorie_number() const { return m_calorie_number; } // How many filters this detector uses to read Calorie numbers in parallel. - // Call OCR::ensure_instances() in SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h + // Call OCR::ensure_ocr_instances() in SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h // to warm OCR object cache so it won't be slow the first time running the detector. static void warm_ocr(); diff --git a/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.cpp b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.cpp index eeba023521..bcf27d1594 100644 --- a/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.cpp +++ b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.cpp @@ -4,7 +4,6 @@ * */ -#include "CommonTools/OCR/OCR_RawOCR.h" #include "PokemonLZA_HyperspaceRewardNameReader.h" namespace PokemonAutomation{ diff --git a/SerialPrograms/Source/PokemonPokopia/Inference/PokemonPokopia_PCDetection.cpp b/SerialPrograms/Source/PokemonPokopia/Inference/PokemonPokopia_PCDetection.cpp index 8a35957c90..8a89bfa53c 100644 --- a/SerialPrograms/Source/PokemonPokopia/Inference/PokemonPokopia_PCDetection.cpp +++ b/SerialPrograms/Source/PokemonPokopia/Inference/PokemonPokopia_PCDetection.cpp @@ -13,7 +13,6 @@ #include "CommonTools/Images/WaterfillUtilities.h" #include "CommonTools/Images/SolidColorTest.h" #include "CommonTools/OCR/OCR_NumberReader.h" -#include "CommonTools/OCR/OCR_RawOCR.h" #include "PokemonPokopia_PCDetection.h" namespace PokemonAutomation{ diff --git a/SerialPrograms/Source/PokemonSV/Inference/ItemPrinter/PokemonSV_ItemPrinterPrizeReader.cpp b/SerialPrograms/Source/PokemonSV/Inference/ItemPrinter/PokemonSV_ItemPrinterPrizeReader.cpp index c918733bfe..313f1bdcee 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/ItemPrinter/PokemonSV_ItemPrinterPrizeReader.cpp +++ b/SerialPrograms/Source/PokemonSV/Inference/ItemPrinter/PokemonSV_ItemPrinterPrizeReader.cpp @@ -10,7 +10,6 @@ #include "CommonFramework/Tools/GlobalThreadPools.h" #include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" #include "CommonTools/Images/ImageFilter.h" -#include "CommonTools/OCR/OCR_RawOCR.h" #include "CommonTools/OCR/OCR_SmallDictionaryMatcher.h" #include "CommonTools/OCR/OCR_NumberReader.h" #include "PokemonSV_ItemPrinterPrizeReader.h" diff --git a/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_AuctionItemNameReader.cpp b/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_AuctionItemNameReader.cpp index 55df95b4e0..745e794e02 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_AuctionItemNameReader.cpp +++ b/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_AuctionItemNameReader.cpp @@ -4,7 +4,6 @@ * */ -#include "CommonTools/OCR/OCR_RawOCR.h" #include "PokemonSV_AuctionItemNameReader.h" namespace PokemonAutomation{ diff --git a/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_TournamentPrizeNameReader.cpp b/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_TournamentPrizeNameReader.cpp index 3fbab4bbf9..9ac374bc17 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_TournamentPrizeNameReader.cpp +++ b/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_TournamentPrizeNameReader.cpp @@ -4,7 +4,6 @@ * */ -#include "CommonTools/OCR/OCR_RawOCR.h" #include "PokemonSV_TournamentPrizeNameReader.h" namespace PokemonAutomation{ From bda0fbbd3ca4516183dedb7e128e0b7eab99d74f Mon Sep 17 00:00:00 2001 From: jw098 Date: Thu, 25 Jun 2026 22:57:32 -0700 Subject: [PATCH 4/7] add comment --- SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp index 208f15ef30..530ffc3489 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp @@ -24,6 +24,9 @@ namespace PokemonAutomation{ namespace OCR{ // return true if the user enabled PaddleOCR and its resource has been downloaded +// NOTE: we are making the assumption that if English is downloaded, +// that all the other languages are downloaded too, since they're all downloaded +// as a bundle. bool use_paddle_ocr(){ static bool use_paddle_ocr = GlobalSettings::instance().USE_PADDLE_OCR && paddle_ocr_language_available(Language::English); From cac27c942aa1f55ea7153c0a58f6ffecda1c5325 Mon Sep 17 00:00:00 2001 From: jw098 Date: Thu, 25 Jun 2026 23:05:07 -0700 Subject: [PATCH 5/7] more comments --- SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h | 4 ++++ SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h b/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h index 6f648c1fc2..ab80341214 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h @@ -4,6 +4,10 @@ * */ +// NOTE: This file should only be inluded in OCR_Routines.h +// This file should not be inluded in other files. +// Use OCR_Routines.h instead + #ifndef PokemonAutomation_CommonTools_OCR_RawOCR_H #define PokemonAutomation_CommonTools_OCR_RawOCR_H diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.h b/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.h index ba57d3f630..6d9e9df795 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.h @@ -4,6 +4,10 @@ * */ +// NOTE: This file should only be inluded in OCR_Routines.h +// This file should not be inluded in other files. +// Use OCR_Routines.h instead + #ifndef PokemonAutomation_CommonTools_OCR_RawPaddleOCR_H #define PokemonAutomation_CommonTools_OCR_RawPaddleOCR_H From 5b459d3d95d08880ac1c88b7cd6b3c4b74a83bae Mon Sep 17 00:00:00 2001 From: jw098 Date: Thu, 25 Jun 2026 23:10:27 -0700 Subject: [PATCH 6/7] more header cleanup --- SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp index 14750d4d10..c4de7da5f0 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp @@ -5,8 +5,6 @@ */ #include "Common/Cpp/Filesystem.h" -#include "CommonFramework/Globals.h" -#include "CommonFramework/Logging/Logger.h" #include "Common/Cpp/Exceptions.h" #include "Common/Cpp/Concurrency/SpinLock.h" #include "CommonFramework/ImageTypes/ImageViewRGB32.h" @@ -103,7 +101,6 @@ std::string paddle_ocr_read(Language language, const ImageViewRGB32& image){ // static size_t c = 0; // image.save("ocr-" + std::to_string(c++) + ".png"); - ML::PaddleOCRPipeline& paddle_instance = ensure_paddle_ocr_instance(language); // Run inference with the paddle model. From b20bc7f82471a9223a7e961aab13dc5c069ef19b Mon Sep 17 00:00:00 2001 From: jw098 Date: Fri, 26 Jun 2026 09:42:04 -0700 Subject: [PATCH 7/7] Rename OCR_RawOCR to OCR_RawTesseractOCR --- SerialPrograms/Source/CommonTools/OCR/OCR_DictionaryMatcher.h | 4 ++-- .../OCR/{OCR_RawOCR.cpp => OCR_RawTesseractOCR.cpp} | 2 +- .../CommonTools/OCR/{OCR_RawOCR.h => OCR_RawTesseractOCR.h} | 4 ++-- SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp | 2 +- SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h | 4 ++-- SerialPrograms/cmake/SourceFiles.cmake | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) rename SerialPrograms/Source/CommonTools/OCR/{OCR_RawOCR.cpp => OCR_RawTesseractOCR.cpp} (96%) rename SerialPrograms/Source/CommonTools/OCR/{OCR_RawOCR.h => OCR_RawTesseractOCR.h} (92%) diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_DictionaryMatcher.h b/SerialPrograms/Source/CommonTools/OCR/OCR_DictionaryMatcher.h index a1c9ffff22..175cacaff5 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_DictionaryMatcher.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_DictionaryMatcher.h @@ -42,7 +42,7 @@ class DictionaryMatcher{ // It specifies the minimum separation between the best candidate and // 2nd best candidate's log10p for it to not be considered ambiguous. // psm: Tesseract Page Segmentation mode. See - // SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h:PageSegMode + // SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.h:PageSegMode OCR::StringMatchResult match_substring_from_image( Logger* logger, Language language, @@ -69,7 +69,7 @@ class DictionaryMatcher{ // even attempts to OCR. This is useful for pruning images with no appearant texts to // reduce expensive OCR computation. // psm: Tesseract Page Segmentation mode. See - // SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h:PageSegMode + // SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.h:PageSegMode OCR::StringMatchResult match_substring_from_image_multifiltered( Logger* logger, Language language, diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.cpp similarity index 96% rename from SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.cpp rename to SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.cpp index ab455bb89c..197361df7c 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.cpp @@ -14,7 +14,7 @@ #include "CommonFramework/Globals.h" #include "CommonFramework/Logging/Logger.h" #include "CommonFramework/ImageTypes/ImageViewRGB32.h" -#include "OCR_RawOCR.h" +#include "OCR_RawTesseractOCR.h" #include using std::cout; diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h b/SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.h similarity index 92% rename from SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h rename to SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.h index ab80341214..cccbfeb8ea 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.h @@ -8,8 +8,8 @@ // This file should not be inluded in other files. // Use OCR_Routines.h instead -#ifndef PokemonAutomation_CommonTools_OCR_RawOCR_H -#define PokemonAutomation_CommonTools_OCR_RawOCR_H +#ifndef PokemonAutomation_CommonTools_OCR_RawTesseractOCR_H +#define PokemonAutomation_CommonTools_OCR_RawTesseractOCR_H #include #include "CommonFramework/Language.h" diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp index 530ffc3489..caba07d131 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp @@ -10,7 +10,7 @@ #include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonTools/Images/ImageFilter.h" #include "OCR_RawPaddleOCR.h" -#include "OCR_RawOCR.h" +#include "OCR_RawTesseractOCR.h" #include "OCR_DictionaryMatcher.h" #include "OCR_Routines.h" diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h index d7236b12af..9a53fce4a3 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h @@ -10,7 +10,7 @@ #include #include #include "CommonFramework/Language.h" -#include "OCR_RawOCR.h" +#include "OCR_RawTesseractOCR.h" namespace PokemonAutomation{ class ImageViewRGB32; @@ -39,7 +39,7 @@ void ensure_ocr_instances(Language language, size_t instances = 1); void clear_ocr_cache(); // psm: Tesseract Page Segmentation mode. See -// SerialPrograms/Source/CommonTools/OCR/OCR_RawOCR.h:PageSegMode +// SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.h:PageSegMode StringMatchResult multifiltered_OCR( Language language, const DictionaryMatcher& dictionary, const ImageViewRGB32& image, const std::vector& text_color_ranges, diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index 95e9cc92d5..1f09aad7ef 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -659,8 +659,8 @@ file(GLOB LIBRARY_SOURCES Source/CommonTools/OCR/OCR_NumberReader.h Source/CommonTools/OCR/OCR_RawPaddleOCR.cpp Source/CommonTools/OCR/OCR_RawPaddleOCR.h - Source/CommonTools/OCR/OCR_RawOCR.cpp - Source/CommonTools/OCR/OCR_RawOCR.h + Source/CommonTools/OCR/OCR_RawTesseractOCR.cpp + Source/CommonTools/OCR/OCR_RawTesseractOCR.h Source/CommonTools/OCR/OCR_Routines.cpp Source/CommonTools/OCR/OCR_Routines.h Source/CommonTools/OCR/OCR_SmallDictionaryMatcher.cpp