From cff71658feb21fc1ad76e26916acfd8bb47fe446 Mon Sep 17 00:00:00 2001 From: jw098 Date: Tue, 21 Jul 2026 15:58:21 -0700 Subject: [PATCH 1/7] change default PageSegMode to SINGLE_LINE. --- .../Source/CommonTools/OCR/OCR_DictionaryMatcher.h | 4 ++-- SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.h | 4 ++-- SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h | 6 +++--- .../PokemonSV/Inference/PokemonSV_BlueberryQuestReader.cpp | 3 ++- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_DictionaryMatcher.h b/SerialPrograms/Source/CommonTools/OCR/OCR_DictionaryMatcher.h index 175cacaff5..5d2a52568e 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_DictionaryMatcher.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_DictionaryMatcher.h @@ -48,7 +48,7 @@ class DictionaryMatcher{ Language language, const ImageViewRGB32& image, double max_log10p, double log10p_spread = 0.5, - OCR::PageSegMode psm = OCR::PageSegMode::SINGLE_BLOCK + OCR::PageSegMode psm = OCR::PageSegMode::SINGLE_LINE ) const; // Match a substring from `image` using multiple black-white filters. @@ -77,7 +77,7 @@ class DictionaryMatcher{ const std::vector& text_color_ranges, double max_log10p, double log10p_spread = 0.5, double min_text_ratio = 0.01, double max_text_ratio = 0.50, - OCR::PageSegMode psm = OCR::PageSegMode::SINGLE_BLOCK + OCR::PageSegMode psm = OCR::PageSegMode::SINGLE_LINE ) const; diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.h b/SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.h index cccbfeb8ea..9b91188f0e 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.h @@ -54,11 +54,11 @@ bool tesseract_language_available(Language language); // 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. +// Defaults to SINGLE_LINE std::string tesseract_ocr_read( Language language, const ImageViewRGB32& image, - PageSegMode psm = PageSegMode::SINGLE_BLOCK + PageSegMode psm = PageSegMode::SINGLE_LINE ); diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h index 1614cd3201..158165c513 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h @@ -32,7 +32,7 @@ struct TextColorRange{ bool ocr_language_available(Language language); -std::string ocr_read(Language language, const ImageViewRGB32& image, PageSegMode psm = PageSegMode::SINGLE_BLOCK); +std::string ocr_read(Language language, const ImageViewRGB32& image, PageSegMode psm = PageSegMode::SINGLE_LINE); void ensure_ocr_instances(Language language, size_t instances = 1); @@ -45,12 +45,12 @@ StringMatchResult multifiltered_OCR( const std::vector& text_color_ranges, double log10p_spread, double min_text_ratio = 0.01, double max_text_ratio = 0.50, - OCR::PageSegMode psm = OCR::PageSegMode::SINGLE_BLOCK + OCR::PageSegMode psm = OCR::PageSegMode::SINGLE_LINE ); StringMatchResult dictionary_OCR( Language language, const DictionaryMatcher& dictionary, const ImageViewRGB32& image, - double log10p_spread, OCR::PageSegMode psm = OCR::PageSegMode::SINGLE_BLOCK + double log10p_spread, OCR::PageSegMode psm = OCR::PageSegMode::SINGLE_LINE ); diff --git a/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_BlueberryQuestReader.cpp b/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_BlueberryQuestReader.cpp index aa6b0dacc2..c252b6e202 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_BlueberryQuestReader.cpp +++ b/SerialPrograms/Source/PokemonSV/Inference/PokemonSV_BlueberryQuestReader.cpp @@ -29,7 +29,8 @@ OCR::StringMatchResult BlueberryQuestReader::read_substring( ) const{ return match_substring_from_image_multifiltered( &logger, language, image, text_color_ranges, - MAX_LOG10P, MAX_LOG10P_SPREAD, min_text_ratio, max_text_ratio + MAX_LOG10P, MAX_LOG10P_SPREAD, min_text_ratio, max_text_ratio, + OCR::PageSegMode::SINGLE_BLOCK ); } From ae14aa2ca6fc7156c128d8e0e4dab10bde2d9d71 Mon Sep 17 00:00:00 2001 From: jw098 Date: Wed, 22 Jul 2026 12:48:34 -0700 Subject: [PATCH 2/7] update error message --- Common/Cpp/Exceptions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/Cpp/Exceptions.cpp b/Common/Cpp/Exceptions.cpp index 301fc07318..f344b9c0a5 100644 --- a/Common/Cpp/Exceptions.cpp +++ b/Common/Cpp/Exceptions.cpp @@ -144,7 +144,7 @@ MLModelSessionCreationError::MLModelSessionCreationError(Logger* logger, std::st std::string MLModelSessionCreationError::message() const{ return std::format( "Failed to create a model session from {}. " - "Probably failure loading the model or not enough GPU memory", + "Probably failure loading the model or not enough GPU memory. Or, the ONNX model may not have been downloaded.", m_model_path ); } From 8cc5df49877bdc5728572c5d4824d0f08a43f237 Mon Sep 17 00:00:00 2001 From: jw098 Date: Wed, 22 Jul 2026 22:28:48 -0700 Subject: [PATCH 3/7] update ocr_read() --- .../Source/CommonTools/OCR/OCR_Routines.cpp | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp index 32f9090fd7..fc553649ea 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp @@ -23,18 +23,9 @@ using std::endl; 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); - - return use_paddle_ocr; -} bool ocr_language_available(Language language){ - if (use_paddle_ocr()){ + if (GlobalSettings::instance().USE_PADDLE_OCR){ return OCR::paddle_ocr_language_available(language); }else{ return OCR::tesseract_language_available(language); @@ -44,16 +35,21 @@ bool ocr_language_available(Language language){ std::string ocr_read(Language language, const ImageViewRGB32& image, PageSegMode psm){ std::string ocr_text = ""; - if (use_paddle_ocr()){ - ocr_text = OCR::paddle_ocr_read(language, image); - }else{ + if (psm == PageSegMode::AUTO || psm == PageSegMode::SINGLE_BLOCK || psm == PageSegMode::SINGLE_COLUMN){ + // if using multiline detection, force Tesseract ocr_text = OCR::tesseract_ocr_read(language, image, psm); + }else{ + if (GlobalSettings::instance().USE_PADDLE_OCR){ + ocr_text = OCR::paddle_ocr_read(language, image); + }else{ + ocr_text = OCR::tesseract_ocr_read(language, image, psm); + } } return ocr_text; } void ensure_ocr_instances(Language language, size_t instances){ - if (use_paddle_ocr()){ + if (GlobalSettings::instance().USE_PADDLE_OCR){ OCR::ensure_paddle_ocr_instance(language); }else{ OCR::ensure_tesseract_instances(language, instances); @@ -61,7 +57,7 @@ void ensure_ocr_instances(Language language, size_t instances){ } void clear_ocr_cache(){ - if (use_paddle_ocr()){ + if (GlobalSettings::instance().USE_PADDLE_OCR){ OCR::clear_paddle_ocr_cache(); }else{ OCR::clear_tesseract_cache(); From 18e9208ef12d94320a0068d4910b54e58d0755d2 Mon Sep 17 00:00:00 2001 From: jw098 Date: Wed, 22 Jul 2026 23:04:23 -0700 Subject: [PATCH 4/7] replace USE_PADDLE_OCR checkbox with OCR_LIBRARY dropdown --- .../CommonFramework/GlobalSettingsPanel.cpp | 19 +++++++++++-------- .../CommonFramework/GlobalSettingsPanel.h | 7 ++++++- .../Source/CommonTools/OCR/OCR_Routines.cpp | 8 ++++---- .../PokemonFRLG_BattleLevelUpReader.cpp | 2 +- .../Inference/PokemonFRLG_DigitReader.h | 2 +- .../PokemonFRLG_PartyLevelUpReader.cpp | 2 +- .../Inference/PokemonFRLG_StatsReader.cpp | 4 ++-- .../Inference/PokemonFRLG_TrainerIdReader.cpp | 2 +- 8 files changed, 27 insertions(+), 19 deletions(-) diff --git a/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp b/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp index 571adc2814..77e7688f33 100644 --- a/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp +++ b/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp @@ -141,11 +141,14 @@ GlobalSettings::GlobalSettings() #endif ) , THEME(CONSTRUCT_TOKEN) - , USE_PADDLE_OCR( - "Enable PaddleOCR:
" - "Use PaddleOCR instead of Tesseract for OCR.", - LockMode::UNLOCK_WHILE_RUNNING, - false + , OCR_LIBRARY( + "OCR library:", + { + {OcrLibrary::PADDLE_OCR, "paddle-ocr", "Paddle OCR"}, + {OcrLibrary::TESSERACT, "tesseract", "Tesseract"}, + }, + LockMode::LOCK_WHILE_RUNNING, + OcrLibrary::PADDLE_OCR ) , USE_GPU_FOR_ML_INFERENCE( "Use GPU for Machine learning inference:
" @@ -275,7 +278,7 @@ GlobalSettings::GlobalSettings() PA_ADD_OPTION(USE_GPU_FOR_ML_INFERENCE); // gated behind Dev mode. see GlobalSettings::load_json - PA_ADD_OPTION(USE_PADDLE_OCR); + PA_ADD_OPTION(OCR_LIBRARY); PA_ADD_OPTION(RESOURCE_DOWNLOAD_TABLE); PA_ADD_OPTION(DOWNLOAD_ERROR); @@ -324,7 +327,7 @@ GlobalSettings::GlobalSettings() PA_ADD_OPTION(DEVELOPER_TOKEN); - USE_PADDLE_OCR.set_visibility(ConfigOptionState::HIDDEN); + OCR_LIBRARY.set_visibility(ConfigOptionState::HIDDEN); RESOURCE_DOWNLOAD_TABLE.set_visibility(ConfigOptionState::HIDDEN); DOWNLOAD_ERROR.set_visibility(ConfigOptionState::HIDDEN); SAVE_DEBUG_VIDEOS_ON_SWITCH.set_visibility(ConfigOptionState::HIDDEN); @@ -348,7 +351,7 @@ void GlobalSettings::load_json(const JsonValue& json){ ConfigOptionState devmode_visibility = developer_mode ? ConfigOptionState::ENABLED : ConfigOptionState::HIDDEN; - USE_PADDLE_OCR.set_visibility(devmode_visibility); + OCR_LIBRARY.set_visibility(devmode_visibility); RESOURCE_DOWNLOAD_TABLE.set_visibility(devmode_visibility); DOWNLOAD_ERROR.set_visibility(devmode_visibility); SAVE_DEBUG_VIDEOS_ON_SWITCH.set_visibility(devmode_visibility); diff --git a/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.h b/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.h index dd494c8a6d..737907c750 100644 --- a/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.h +++ b/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.h @@ -9,6 +9,7 @@ #include #include "Common/Cpp/Containers/Pimpl.h" +#include "Common/Cpp/Options/EnumDropdownOption.h" #include "Common/Cpp/Options/ConfigOption.h" #include "Common/Cpp/Options/StaticTextOption.h" #include "Common/Cpp/Options/BooleanCheckBoxOption.h" @@ -42,6 +43,10 @@ class ErrorReportOption; class ResourceDownload; +enum class OcrLibrary{ + PADDLE_OCR, + TESSERACT, +}; class FolderInputOption : public StringOption{ public: @@ -127,7 +132,7 @@ class GlobalSettings : public BatchOption, private ConfigOption::Listener, priva FolderInputOption TEMP_FOLDER; Pimpl THEME; - BooleanCheckBoxOption USE_PADDLE_OCR; + EnumDropdownOption OCR_LIBRARY; BooleanCheckBoxOption USE_GPU_FOR_ML_INFERENCE; SettingsResourceDownloadTable RESOURCE_DOWNLOAD_TABLE; SettingsDownloadError DOWNLOAD_ERROR; diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp index fc553649ea..cc63bbee63 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp @@ -25,7 +25,7 @@ namespace OCR{ bool ocr_language_available(Language language){ - if (GlobalSettings::instance().USE_PADDLE_OCR){ + if (GlobalSettings::instance().OCR_LIBRARY == OcrLibrary::PADDLE_OCR){ return OCR::paddle_ocr_language_available(language); }else{ return OCR::tesseract_language_available(language); @@ -39,7 +39,7 @@ std::string ocr_read(Language language, const ImageViewRGB32& image, PageSegMode // if using multiline detection, force Tesseract ocr_text = OCR::tesseract_ocr_read(language, image, psm); }else{ - if (GlobalSettings::instance().USE_PADDLE_OCR){ + if (GlobalSettings::instance().OCR_LIBRARY == OcrLibrary::PADDLE_OCR){ ocr_text = OCR::paddle_ocr_read(language, image); }else{ ocr_text = OCR::tesseract_ocr_read(language, image, psm); @@ -49,7 +49,7 @@ std::string ocr_read(Language language, const ImageViewRGB32& image, PageSegMode } void ensure_ocr_instances(Language language, size_t instances){ - if (GlobalSettings::instance().USE_PADDLE_OCR){ + if (GlobalSettings::instance().OCR_LIBRARY == OcrLibrary::PADDLE_OCR){ OCR::ensure_paddle_ocr_instance(language); }else{ OCR::ensure_tesseract_instances(language, instances); @@ -57,7 +57,7 @@ void ensure_ocr_instances(Language language, size_t instances){ } void clear_ocr_cache(){ - if (GlobalSettings::instance().USE_PADDLE_OCR){ + if (GlobalSettings::instance().OCR_LIBRARY == OcrLibrary::PADDLE_OCR){ OCR::clear_paddle_ocr_cache(); }else{ OCR::clear_tesseract_cache(); diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_BattleLevelUpReader.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_BattleLevelUpReader.cpp index eeccc9c9c2..770ba43357 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_BattleLevelUpReader.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_BattleLevelUpReader.cpp @@ -55,7 +55,7 @@ StatReads BattleLevelUpReader::read_stats(Logger &logger, const ImageViewRGB32& auto read_stat = [&](const ImageFloatBox &box, const std::string &name){ ImageViewRGB32 stat_region = extract_box_reference(game_screen, box); - if (!GlobalSettings::instance().USE_PADDLE_OCR){ + if (GlobalSettings::instance().OCR_LIBRARY != OcrLibrary::PADDLE_OCR){ // Tesseract-free path: waterfill segmentation + template matching // against the PokemonFRLG/Digits/0-9.png templates. return read_digits_waterfill_template(logger, stat_region); diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_DigitReader.h b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_DigitReader.h index 15f6898bce..7f01cf9557 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_DigitReader.h +++ b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_DigitReader.h @@ -7,7 +7,7 @@ * then template-matches each cropped digit against the pre-stored digit * templates (Resources/PokemonFRLG/Digits/0-9.png) on the unblurred original. * - * This is the Tesseract/PaddleOCR-free fallback path for USE_PADDLE_OCR=false. + * This is the Tesseract (PaddleOCR-free) fallback path. */ #ifndef PokemonAutomation_PokemonFRLG_DigitReader_H diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_PartyLevelUpReader.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_PartyLevelUpReader.cpp index 4c9a26ce4d..bc4f5f0e46 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_PartyLevelUpReader.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_PartyLevelUpReader.cpp @@ -55,7 +55,7 @@ StatReads PartyLevelUpReader::read_stats(Logger &logger, const ImageViewRGB32& f auto read_stat = [&](const ImageFloatBox &box, const std::string &name){ ImageViewRGB32 stat_region = extract_box_reference(game_screen, box); - if (!GlobalSettings::instance().USE_PADDLE_OCR){ + if (GlobalSettings::instance().OCR_LIBRARY != OcrLibrary::PADDLE_OCR){ // Tesseract-free path: waterfill segmentation + template matching // against the PokemonFRLG/Digits/0-9.png templates. return read_digits_waterfill_template(logger, stat_region); diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_StatsReader.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_StatsReader.cpp index 3e528bcc95..9fab647c8d 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_StatsReader.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_StatsReader.cpp @@ -191,7 +191,7 @@ void StatsReader::read_level( ImageViewRGB32 level_box = extract_box_reference(game_screen, jpn ? m_box_level_jpn : m_box_level); - if (!GlobalSettings::instance().USE_PADDLE_OCR){ + if (GlobalSettings::instance().OCR_LIBRARY != OcrLibrary::PADDLE_OCR){ // The level uses white text with dark shadow on a lilac background. // The digit reader's binarizer captures dark pixels (<=190 on all channels) // but NOT the white text (all channels 255 -> excluded). This leaves the @@ -335,7 +335,7 @@ void StatsReader::read_page2( auto read_stat = [&](const ImageFloatBox& box, const std::string& name){ ImageViewRGB32 stat_region = extract_box_reference(game_screen, box); - if (!GlobalSettings::instance().USE_PADDLE_OCR){ + if (GlobalSettings::instance().OCR_LIBRARY != OcrLibrary::PADDLE_OCR){ // Tesseract-free path: waterfill segmentation + template matching // against the PokemonFRLG/Digits/0-9.png templates. return read_digits_waterfill_template(logger, stat_region); diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.cpp index 799ea19442..c8e4c17cba 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.cpp @@ -43,7 +43,7 @@ uint16_t TrainerIdReader::read_tid( ImageViewRGB32 tid_region = extract_box_reference(game_screen, language == Language::Japanese ? m_box_tid_jpn : m_box_tid); - if (!GlobalSettings::instance().USE_PADDLE_OCR){ + if (GlobalSettings::instance().OCR_LIBRARY != OcrLibrary::PADDLE_OCR){ // Tesseract-free path: waterfill segmentation + template matching // against the PokemonFRLG/Digits/0-9.png templates. return uint16_t(read_digits_waterfill_template(logger, tid_region)); From 57ff3a363ad153abbaea73252c8afbcaf37e0f91 Mon Sep 17 00:00:00 2001 From: jw098 Date: Wed, 22 Jul 2026 23:10:35 -0700 Subject: [PATCH 5/7] update error messages --- Common/Cpp/Exceptions.cpp | 2 +- SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Common/Cpp/Exceptions.cpp b/Common/Cpp/Exceptions.cpp index f344b9c0a5..1397166abb 100644 --- a/Common/Cpp/Exceptions.cpp +++ b/Common/Cpp/Exceptions.cpp @@ -144,7 +144,7 @@ MLModelSessionCreationError::MLModelSessionCreationError(Logger* logger, std::st std::string MLModelSessionCreationError::message() const{ return std::format( "Failed to create a model session from {}. " - "Probably failure loading the model or not enough GPU memory. Or, the ONNX model may not have been downloaded.", + "Probably failure loading the model or not enough GPU memory. Also, ensure that the corresponding ONNX model has been downloaded.", m_model_path ); } diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.cpp b/SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.cpp index 197361df7c..f1f382c00f 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.cpp +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_RawTesseractOCR.cpp @@ -111,7 +111,7 @@ class TesseractPool{ new TesseractAPI(m_training_data_path.c_str(), m_language_code.c_str()) ); if (!api->valid()){ - throw InternalSystemError(nullptr, PA_CURRENT_FUNCTION, "Could not initialize TesseractAPI."); + throw InternalSystemError(nullptr, PA_CURRENT_FUNCTION, "Could not initialize TesseractAPI. Ensure that Tesseract has been downloaded."); } // Add to pool under lock. From 696181a1971c9b180746ebf9695d5b444057c374 Mon Sep 17 00:00:00 2001 From: jw098 Date: Wed, 22 Jul 2026 23:30:05 -0700 Subject: [PATCH 6/7] add OCR_WARNING static text --- .../Source/CommonFramework/GlobalSettingsPanel.cpp | 5 +++++ SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.h | 1 + SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h | 3 +++ 3 files changed, 9 insertions(+) diff --git a/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp b/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp index 77e7688f33..a2e8d4d376 100644 --- a/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp +++ b/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp @@ -150,6 +150,10 @@ GlobalSettings::GlobalSettings() LockMode::LOCK_WHILE_RUNNING, OcrLibrary::PADDLE_OCR ) + , OCR_WARNING( + "WARNING: If you change the OCR library away from the default (PaddleOCR), you must ensure that you have the necessary resource downloaded. " + "Otherwise, the programs that use OCR will throw an error." + ) , USE_GPU_FOR_ML_INFERENCE( "Use GPU for Machine learning inference:
" "Use the GPU by default for machine learning. Will fall-back to CPU if using the GPU fails.", @@ -279,6 +283,7 @@ GlobalSettings::GlobalSettings() // gated behind Dev mode. see GlobalSettings::load_json PA_ADD_OPTION(OCR_LIBRARY); + // PA_ADD_OPTION(OCR_WARNING); // TODO: enable this when Tesseract is no longer a default resource. PA_ADD_OPTION(RESOURCE_DOWNLOAD_TABLE); PA_ADD_OPTION(DOWNLOAD_ERROR); diff --git a/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.h b/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.h index 737907c750..46d897db73 100644 --- a/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.h +++ b/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.h @@ -133,6 +133,7 @@ class GlobalSettings : public BatchOption, private ConfigOption::Listener, priva Pimpl THEME; EnumDropdownOption OCR_LIBRARY; + StaticTextOption OCR_WARNING; BooleanCheckBoxOption USE_GPU_FOR_ML_INFERENCE; SettingsResourceDownloadTable RESOURCE_DOWNLOAD_TABLE; SettingsDownloadError DOWNLOAD_ERROR; diff --git a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h index 158165c513..037e433553 100644 --- a/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h +++ b/SerialPrograms/Source/CommonTools/OCR/OCR_Routines.h @@ -32,6 +32,9 @@ struct TextColorRange{ bool ocr_language_available(Language language); +// will use the OCR library as per the dropdown in GlobalSettings +// if the preferred library's resource is missing (i.e. it has not been downloaded), +// an error will be thrown within OCR initialization infra. std::string ocr_read(Language language, const ImageViewRGB32& image, PageSegMode psm = PageSegMode::SINGLE_LINE); void ensure_ocr_instances(Language language, size_t instances = 1); From 9263807348359ea7e847aaa8434e412707be3dc6 Mon Sep 17 00:00:00 2001 From: jw098 Date: Thu, 23 Jul 2026 09:41:34 -0700 Subject: [PATCH 7/7] change default OCR back to Tesseract --- SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp b/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp index a2e8d4d376..868919af8f 100644 --- a/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp +++ b/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp @@ -148,7 +148,7 @@ GlobalSettings::GlobalSettings() {OcrLibrary::TESSERACT, "tesseract", "Tesseract"}, }, LockMode::LOCK_WHILE_RUNNING, - OcrLibrary::PADDLE_OCR + OcrLibrary::TESSERACT ) , OCR_WARNING( "WARNING: If you change the OCR library away from the default (PaddleOCR), you must ensure that you have the necessary resource downloaded. "