From d8910941e78bdf0707e738130c4eb8fe239630f6 Mon Sep 17 00:00:00 2001 From: MistEO Date: Sun, 29 May 2022 22:37:40 +0800 Subject: [PATCH] =?UTF-8?q?perf.=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E5=85=B3=E5=8D=A1=E6=8E=89=E8=90=BD=E8=AF=86=E5=88=AB=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=85=B3=E5=8D=A1=E6=8E=89=E8=90=BD=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E7=9A=84=E8=AF=86=E5=88=AB=E9=80=9F=E5=BA=A6=EF=BC=88=E4=B8=8D?= =?UTF-8?q?split=E4=BA=86=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MeoAssistant/StageDropsImageAnalyzer.cpp | 114 +++++++++---------- 1 file changed, 53 insertions(+), 61 deletions(-) diff --git a/src/MeoAssistant/StageDropsImageAnalyzer.cpp b/src/MeoAssistant/StageDropsImageAnalyzer.cpp index e17b4c85f7..2ff7ac5489 100644 --- a/src/MeoAssistant/StageDropsImageAnalyzer.cpp +++ b/src/MeoAssistant/StageDropsImageAnalyzer.cpp @@ -1,7 +1,7 @@ #include "StageDropsImageAnalyzer.h" #include "TaskData.h" -#include "OcrImageAnalyzer.h" +#include "OcrWithPreprocessImageAnalyzer.h" #include "MatchImageAnalyzer.h" #include "Resource.h" #include "AsstUtils.hpp" @@ -255,11 +255,17 @@ bool asst::StageDropsImageAnalyzer::analyze_baseline() int threshold = task_ptr->mask_range.first; uchar pre_value = 0; for (int i = 0; i < bounding.cols; ++i) { - uchar value = bounding.at(0, i); - bool is_white = value > threshold && pre_value - value < threshold; - pre_value = value; + bool has_white = false; + for (int j = 0; j < bounding.rows; ++j) { + uchar value = bounding.at(j, i); + pre_value = value; + if (value > threshold && pre_value - value < threshold) { + has_white = true; + break; + } + } - if (in && !is_white) { + if (in && !has_white) { in = false; iend = i; int width = iend - istart; @@ -272,7 +278,7 @@ bool asst::StageDropsImageAnalyzer::analyze_baseline() m_baseline.emplace_back(baseline, match_droptype(baseline)); } } - else if (!in && is_white) { + else if (!in && has_white) { istart = i; in = true; } @@ -473,64 +479,50 @@ int asst::StageDropsImageAnalyzer::match_quantity(const Rect& roi) } } - OcrImageAnalyzer analyzer(m_image); + // 前面的 split 算法经过了大量的测试集验证,分割效果一切正常 + // 后来发现不需要 split 了(为了优化识别速度),但是这个算法不太敢动,怕出问题 + // 所以这里保留前面的 split 算法,直接取两侧端点。(反正前面跑几个循环也费不了多长时间) + int far_left = contours.back().start; + int far_right = contours.front().end; + + OcrWithPreprocessImageAnalyzer analyzer(m_image); analyzer.set_task_info("NumberOcrReplace"); - analyzer.set_use_cache(true); + analyzer.set_roi(Rect(quantity_roi.x + far_left, quantity_roi.y, far_right - far_left, quantity_roi.height)); + analyzer.set_expansion(1); + analyzer.set_threshold(task_ptr->mask_range.first, task_ptr->mask_range.second); - int quantity = 0; - for (auto riter = contours.crbegin(); riter != contours.crend(); ++riter) { - auto& range = *riter; - cv::Mat range_img = bin(cv::Range::all(), range); - cv::Rect rect = cv::boundingRect(range_img); - cv::Mat bounding = range_img(rect); - - Rect absolute_rect; - absolute_rect.x = quantity_roi.x + rect.x + range.start - 1; - absolute_rect.y = quantity_roi.y + rect.y - 1; - absolute_rect.width = rect.width + 2; - absolute_rect.height = rect.height + 2; - -#ifdef ASST_DEBUG - cv::rectangle(m_image_draw, utils::make_rect(absolute_rect), cv::Scalar(0, 255, 0), 1); -#endif - - analyzer.set_region_of_appeared(absolute_rect); - if (!analyzer.analyze()) { - return 0; - } - auto digit_str = analyzer.get_result().front().text; -#ifdef ASST_DEBUG - cv::putText(m_image_draw, digit_str, cv::Point(absolute_rect.x, absolute_rect.y - 5), - cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 2); -#endif - int dot = 0; - if (digit_str == "万") { - quantity *= 10000; - } - else if (digit_str == "亿") { - quantity *= 100000000; - } - else if (digit_str.size() == 1) { - if (char c = digit_str[0]; c >= '0' && c <= '9') { - quantity *= 10; - quantity += c - '0'; - if (dot) { - ++dot; - } - } - else if (c == '.') { - dot = 1; - } - } - else { - Log.error("quantity is not a single digit"); - return 0; - } - if (dot > 1) { - quantity /= (dot - 1); - } + if (!analyzer.analyze()) { + return 0; } - Log.info("Quantity:", quantity); + const auto& result = analyzer.get_result().front(); + +#ifdef ASST_DEBUG + cv::rectangle(m_image_draw, utils::make_rect(result.rect), cv::Scalar(0, 0, 255)); + cv::putText(m_image_draw, result.text, cv::Point(result.rect.x, result.rect.y - 5), + cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 2); +#endif + + std::string digit_str = result.text; + int multiple = 1; + if (size_t w_pos = digit_str.find("万"); + w_pos != std::string::npos) { + multiple = 10000; + digit_str.erase(w_pos, digit_str.size()); + } + //else if (size_t e_pos = digit_str.find("亿"); + // e_pos != std::string::npos) { + // multiple = 100000000; + // digit_str.erase(e_pos, digit_str.size()); + //} + + if (digit_str.empty() || + !std::all_of(digit_str.cbegin(), digit_str.cend(), + [](char c) -> bool {return std::isdigit(c) || c == '.';})) { + return 0; + } + + int quantity = static_cast(std::stod(digit_str) * multiple); + Log.info("Quantity:", quantity); return quantity; }