diff --git a/src/MaaCore/Vision/Config/OCRerConfig.cpp b/src/MaaCore/Vision/Config/OCRerConfig.cpp index 5e27c58109..f37e6b05ee 100644 --- a/src/MaaCore/Vision/Config/OCRerConfig.cpp +++ b/src/MaaCore/Vision/Config/OCRerConfig.cpp @@ -61,6 +61,12 @@ void OCRerConfig::set_bin_expansion(int expansion) m_params.bin_expansion = expansion; } +void asst::OCRerConfig::set_bin_trim_threshold(int left, int right) +{ + m_params.bin_left_trim_threshold = left; + m_params.bin_right_trim_threshold = right; +} + void OCRerConfig::_set_task_info(OcrTaskInfo task_info) { set_required(std::move(task_info.text)); diff --git a/src/MaaCore/Vision/Config/OCRerConfig.h b/src/MaaCore/Vision/Config/OCRerConfig.h index da387fe480..f753902ba3 100644 --- a/src/MaaCore/Vision/Config/OCRerConfig.h +++ b/src/MaaCore/Vision/Config/OCRerConfig.h @@ -22,6 +22,8 @@ namespace asst int bin_threshold_lower = 140; int bin_threshold_upper = 255; int bin_expansion = 2; + int bin_left_trim_threshold = 0; + int bin_right_trim_threshold = 0; }; public: @@ -42,6 +44,7 @@ namespace asst void set_bin_threshold(int lower, int upper = 255); void set_bin_expansion(int expansion); + void set_bin_trim_threshold(int left, int right); protected: virtual void _set_roi(const Rect& roi) = 0; diff --git a/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.cpp b/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.cpp index cc642746f3..2eaf3650df 100644 --- a/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.cpp +++ b/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.cpp @@ -8,8 +8,8 @@ #include "Vision/BestMatcher.h" #include "Vision/Matcher.h" #include "Vision/MultiMatcher.h" -#include "Vision/TemplDetOCRer.h" #include "Vision/RegionOCRer.h" +#include "Vision/TemplDetOCRer.h" bool asst::OperBoxImageAnalyzer::analyze() { @@ -63,6 +63,8 @@ bool asst::OperBoxImageAnalyzer::opers_analyze() oper_name_analyzer.set_task_info("OperBoxFlagLV", "OperBoxNameOCR"); oper_name_analyzer.set_replace(ocr_replace->replace_map, ocr_replace->replace_full); + oper_name_analyzer.set_bin_expansion(4); + oper_name_analyzer.set_bin_trim_threshold(4, 0); const auto& all_opers = BattleData.get_all_oper_names(); oper_name_analyzer.set_required(std::vector(all_opers.begin(), all_opers.end())); if (!oper_name_analyzer.analyze()) { @@ -84,7 +86,10 @@ bool asst::OperBoxImageAnalyzer::opers_analyze() box.own = true; #ifdef ASST_DEBUG - cv::rectangle(m_image_draw, make_rect(flag_rect), cv::Scalar(0, 255, 0), 2); + cv::rectangle(m_image_draw, make_rect(flag_rect), cv::Scalar(0, 255, 0), 1); + cv::putText(m_image_draw, std::to_string(oper.flag_score), cv::Point(flag_rect.x + 10, flag_rect.y), + cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 255), 1); + cv::rectangle(m_image_draw, make_rect(oper.rect), cv::Scalar(0, 255, 0), 1); #endif m_result.emplace_back(std::move(box)); @@ -152,6 +157,8 @@ bool asst::OperBoxImageAnalyzer::elite_analyze() box.elite = std::stoi(elite); #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(roi), cv::Scalar(0, 255, 0), 1); + cv::putText(m_image_draw, std::to_string(box.elite), cv::Point(roi.x, roi.y - 10), cv::FONT_HERSHEY_SIMPLEX, + 0.5, cv::Scalar(0, 0, 255), 2); #endif // ASST_DEBUG } return true; @@ -182,6 +189,8 @@ bool asst::OperBoxImageAnalyzer::potential_analyze() box.potential = std::stoi(potential); #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(roi), cv::Scalar(0, 255, 0), 1); + cv::putText(m_image_draw, std::to_string(box.potential), cv::Point(roi.x, roi.y - 10), cv::FONT_HERSHEY_SIMPLEX, + 0.5, cv::Scalar(0, 0, 255), 2); #endif // ASST_DEBUG } return true; diff --git a/src/MaaCore/Vision/OCRer.h b/src/MaaCore/Vision/OCRer.h index 73a9e39bd2..48517ef4cb 100644 --- a/src/MaaCore/Vision/OCRer.h +++ b/src/MaaCore/Vision/OCRer.h @@ -28,6 +28,7 @@ namespace asst // Not working for OCR with detection using OCRerConfig::set_bin_expansion; using OCRerConfig::set_bin_threshold; + using OCRerConfig::set_bin_trim_threshold; protected: void postproc_rect_(Result& res) const; diff --git a/src/MaaCore/Vision/RegionOCRer.cpp b/src/MaaCore/Vision/RegionOCRer.cpp index 44d31b33bc..13c614c306 100644 --- a/src/MaaCore/Vision/RegionOCRer.cpp +++ b/src/MaaCore/Vision/RegionOCRer.cpp @@ -11,6 +11,10 @@ RegionOCRer::ResultOpt RegionOCRer::analyze() const cv::cvtColor(img_roi, img_roi_gray, cv::COLOR_BGR2GRAY); cv::Mat bin; cv::inRange(img_roi_gray, m_params.bin_threshold_lower, m_params.bin_threshold_upper, bin); + + bin_left_trim(bin); + bin_right_trim(bin); + cv::Rect bounding_rect = cv::boundingRect(bin); bounding_rect.x += m_roi.x; bounding_rect.y += m_roi.y; @@ -19,7 +23,6 @@ RegionOCRer::ResultOpt RegionOCRer::analyze() const if (new_roi.empty()) { return std::nullopt; } - // todo: split int exp = m_params.bin_expansion; if (exp) { @@ -45,3 +48,53 @@ RegionOCRer::ResultOpt RegionOCRer::analyze() const m_result = result->front(); return m_result; } + +void asst::RegionOCRer::bin_left_trim(cv::Mat& bin) const +{ + if (!m_params.bin_left_trim_threshold) { + return; + } + + int pre_white_col = 0; + for (int i = 0; i < bin.cols; ++i) { + bool has_white = false; + for (int j = 0; j < bin.rows; ++j) { + if (bin.at(j, i)) { + has_white = true; + break; + } + } + if (has_white) { + pre_white_col = i; + } + else if (i - pre_white_col > m_params.bin_left_trim_threshold) { + bin.colRange(0, i).setTo(0); + break; + } + } +} + +void asst::RegionOCRer::bin_right_trim(cv::Mat& bin) const +{ + if (!m_params.bin_right_trim_threshold) { + return; + } + + int pre_white_col = bin.cols - 1; + for (int i = bin.cols - 1; i >= 0; --i) { + bool has_white = false; + for (int j = 0; j < bin.rows; ++j) { + if (bin.at(j, i)) { + has_white = true; + break; + } + } + if (has_white) { + pre_white_col = i; + } + else if (pre_white_col - i > m_params.bin_right_trim_threshold) { + bin.colRange(i, bin.cols).setTo(0); + break; + } + } +} diff --git a/src/MaaCore/Vision/RegionOCRer.h b/src/MaaCore/Vision/RegionOCRer.h index 48504908ad..b28875e42d 100644 --- a/src/MaaCore/Vision/RegionOCRer.h +++ b/src/MaaCore/Vision/RegionOCRer.h @@ -21,6 +21,9 @@ namespace asst using OCRerConfig::set_without_det; virtual void _set_roi(const Rect& roi) override { set_roi(roi); } + void bin_left_trim(cv::Mat& bin) const; + void bin_right_trim(cv::Mat& bin) const; + private: // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 mutable Result m_result;