diff --git a/resource/tasks.json b/resource/tasks.json index 5259a3088a..b9c0047137 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -2323,30 +2323,6 @@ "[Uu]-[O0o]f{1,2}icial", "U-Official" ], - [ - "^4", - "" - ], - [ - "^α", - "" - ], - [ - "^-", - "" - ], - [ - "—", - "" - ], - [ - ".*12F", - "12F" - ], - [ - "^_", - "" - ], [ ".*威龙陈", "假日威龙陈" @@ -9862,15 +9838,33 @@ 20 ] }, - "OperBoxFlagLV": { - "templThreshold": 0.6, + "OperBoxFlagRoleTopROI": { + "template": "empty.png", "roi": [ - 40, - 310, - 1128, - 327 + 0, + 78, + 1145, + 50 ] }, + "OperBoxFlagRoleBottomROI": { + "template": "empty.png", + "roi": [ + 0, + 394, + 1145, + 50 + ] + }, + "OperBoxFlagRole1": {}, + "OperBoxFlagRole2": {}, + "OperBoxFlagRole3": {}, + "OperBoxFlagRole4": {}, + "OperBoxFlagRole5": {}, + "OperBoxFlagRole6": {}, + "OperBoxFlagRole7": {}, + "OperBoxFlagRole8": {}, + "OperBoxFlagRole9": {}, "OperBoxFlagElite1": { "doc": "精英一 模板" }, @@ -9882,8 +9876,8 @@ "template": "empty.png", "templThreshold": 0.9, "roi": [ - -7, - -52, + 11, + 171, 24, 35 ] @@ -9893,8 +9887,8 @@ "template": "empty.png", "templThreshold": 0.85, "roi": [ - 81, - -29, + 99, + 194, 24, 24 ] @@ -9905,16 +9899,14 @@ "OperBoxPotential4": {}, "OperBoxPotential5": {}, "OperBoxNameOCR": { - "algorithm": "OcrDetect", - "fullMatch": true, + "baseTask": "CharsNameOcrReplace", "text": [], "roi": [ - 5, - 42, - 105, - 20 - ], - "postDelay": 100 + 4, + 269, + 122, + 14 + ] }, "OperBoxLevelOCR": { "algorithm": "OcrDetect", @@ -9922,12 +9914,11 @@ "isAscii": true, "text": [], "roi": [ - -13, - 7, + 5, + 230, 37, 23 - ], - "postDelay": 100 + ] }, "RoguelikeRecruitSwipeMaxTime": { "algorithm": "JustReturn", diff --git a/resource/template/OperBoxFlagLV.png b/resource/template/OperBoxFlagLV.png deleted file mode 100644 index 3baa29f9d2..0000000000 Binary files a/resource/template/OperBoxFlagLV.png and /dev/null differ diff --git a/resource/template/OperBoxFlagRole1.png b/resource/template/OperBoxFlagRole1.png new file mode 100644 index 0000000000..1289ae4d50 Binary files /dev/null and b/resource/template/OperBoxFlagRole1.png differ diff --git a/resource/template/OperBoxFlagRole2.png b/resource/template/OperBoxFlagRole2.png new file mode 100644 index 0000000000..fd0dcab345 Binary files /dev/null and b/resource/template/OperBoxFlagRole2.png differ diff --git a/resource/template/OperBoxFlagRole3.png b/resource/template/OperBoxFlagRole3.png new file mode 100644 index 0000000000..38a6afb597 Binary files /dev/null and b/resource/template/OperBoxFlagRole3.png differ diff --git a/resource/template/OperBoxFlagRole4.png b/resource/template/OperBoxFlagRole4.png new file mode 100644 index 0000000000..31412ff24a Binary files /dev/null and b/resource/template/OperBoxFlagRole4.png differ diff --git a/resource/template/OperBoxFlagRole5.png b/resource/template/OperBoxFlagRole5.png new file mode 100644 index 0000000000..1359b222b4 Binary files /dev/null and b/resource/template/OperBoxFlagRole5.png differ diff --git a/resource/template/OperBoxFlagRole6.png b/resource/template/OperBoxFlagRole6.png new file mode 100644 index 0000000000..e409dfc238 Binary files /dev/null and b/resource/template/OperBoxFlagRole6.png differ diff --git a/resource/template/OperBoxFlagRole7.png b/resource/template/OperBoxFlagRole7.png new file mode 100644 index 0000000000..c5c692b276 Binary files /dev/null and b/resource/template/OperBoxFlagRole7.png differ diff --git a/resource/template/OperBoxFlagRole8.png b/resource/template/OperBoxFlagRole8.png new file mode 100644 index 0000000000..b5acb9cde2 Binary files /dev/null and b/resource/template/OperBoxFlagRole8.png differ diff --git a/resource/template/OperBoxFlagRole9.png b/resource/template/OperBoxFlagRole9.png new file mode 100644 index 0000000000..02436b9560 Binary files /dev/null and b/resource/template/OperBoxFlagRole9.png differ diff --git a/src/MaaCore/Vision/Battle/BattlefieldDetector.cpp b/src/MaaCore/Vision/Battle/BattlefieldDetector.cpp index 3facf67770..2a5f986900 100644 --- a/src/MaaCore/Vision/Battle/BattlefieldDetector.cpp +++ b/src/MaaCore/Vision/Battle/BattlefieldDetector.cpp @@ -118,29 +118,5 @@ std::vector BattlefieldDetector::operator_a all_results.emplace_back(std::move(box)); } - // NMS - constexpr double NmsThreshold = 0.7f; - std::sort(all_results.begin(), all_results.end(), - [](const OperatorResult& a, const OperatorResult& b) { return a.score > b.score; }); - - std::vector nms_results; - for (size_t i = 0; i < all_results.size(); ++i) { - const auto& box = all_results[i]; - if (box.score < 0.1f) { - continue; - } - nms_results.emplace_back(box); - for (size_t j = i + 1; j < all_results.size(); ++j) { - auto& box2 = all_results[j]; - if (box2.score < 0.1f) { - continue; - } - int iou_area = (make_rect(box.rect) & make_rect(box2.rect)).area(); - if (iou_area > NmsThreshold * box2.rect.area()) { - box2.score = 0; - } - } - } - - return nms_results; + return NMS(all_results); } diff --git a/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.cpp b/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.cpp index 2eaf3650df..1bd596b42d 100644 --- a/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.cpp +++ b/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.cpp @@ -4,6 +4,7 @@ #include "Config/Miscellaneous/BattleDataConfig.h" #include "Config/TaskData.h" +#include "Utils/ImageIo.hpp" #include "Utils/Logger.hpp" #include "Vision/BestMatcher.h" #include "Vision/Matcher.h" @@ -57,23 +58,44 @@ bool asst::OperBoxImageAnalyzer::analyzer_oper_box() bool asst::OperBoxImageAnalyzer::opers_analyze() { - const auto& ocr_replace = Task.get("CharsNameOcrReplace"); - TemplDetOCRer oper_name_analyzer(m_image); - 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_threshold(160); 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()) { + + TemplDetOCRer::ResultsVec results; + + Rect roi_top = Task.get("OperBoxFlagRoleTopROI")->roi; + Rect roi_bottom = Task.get("OperBoxFlagRoleBottomROI")->roi; + + for (int i = 1; i < 10; ++i) { + oper_name_analyzer.set_task_info("OperBoxFlagRole" + std::to_string(i), "OperBoxNameOCR"); + + oper_name_analyzer.set_roi(roi_top); + auto top_result_opt = oper_name_analyzer.analyze(); + if (top_result_opt) { + results.insert(results.end(), std::make_move_iterator(top_result_opt->begin()), + std::make_move_iterator(top_result_opt->end())); + } + + oper_name_analyzer.set_roi(roi_bottom); + auto bottom_result_opt = oper_name_analyzer.analyze(); + if (bottom_result_opt) { + results.insert(results.end(), std::make_move_iterator(bottom_result_opt->begin()), + std::make_move_iterator(bottom_result_opt->end())); + } + } + + if (results.empty()) { return false; } - auto result_list = oper_name_analyzer.get_result(); - sort_by_horizontal_(result_list); + results = NMS(results); + sort_by_horizontal_(results); - for (const auto& oper : result_list) { + for (const auto& oper : results) { const Rect& flag_rect = oper.flag_rect; const std::string& name = oper.text; @@ -87,7 +109,7 @@ bool asst::OperBoxImageAnalyzer::opers_analyze() #ifdef ASST_DEBUG 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::putText(m_image_draw, std::to_string(oper.flag_score), cv::Point(flag_rect.x, flag_rect.y - 10), 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 diff --git a/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.h b/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.h index 6dbf778b99..546c91c7bc 100644 --- a/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.h +++ b/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.h @@ -16,6 +16,7 @@ namespace asst Rect rect; bool own = false; }; + class OperBoxImageAnalyzer final : public VisionHelper { public: diff --git a/src/MaaCore/Vision/VisionHelper.h b/src/MaaCore/Vision/VisionHelper.h index 8a19518088..a0561d52c9 100644 --- a/src/MaaCore/Vision/VisionHelper.h +++ b/src/MaaCore/Vision/VisionHelper.h @@ -109,4 +109,31 @@ namespace asst return lvalue < rvalue; }); } + + // Non-Maximum Suppression + template + inline static ResultsVec NMS(ResultsVec& results, double threshold = 0.7) + { + ranges::sort(results, [](const auto& a, const auto& b) { return a.score > b.score; }); + + ResultsVec nms_results; + for (size_t i = 0; i < results.size(); ++i) { + const auto& box = results[i]; + if (box.score < 0.1f) { + continue; + } + nms_results.emplace_back(box); + for (size_t j = i + 1; j < results.size(); ++j) { + auto& box2 = results[j]; + if (box2.score < 0.1f) { + continue; + } + int iou_area = (make_rect(box.rect) & make_rect(box2.rect)).area(); + if (iou_area > threshold * box2.rect.area()) { + box2.score = 0; + } + } + } + return nms_results; + } } // namespace asst