diff --git a/resource/tasks.json b/resource/tasks.json index a1bef9ef41..74460a8184 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -63,6 +63,66 @@ [ "桑甚", "桑葚" + ], + [ + "灰烟", + "灰烬" + ], + [ + "迷.+香", + "迷迭香" + ], + [ + "森.+", + "森蚺" + ], + [ + ".+心斯卡蒂", + "浊心斯卡蒂" + ], + [ + "^会$", + "令" + ], + [ + "归漠幽灵鲨", + "归溟幽灵鲨" + ], + [ + "姜峨", + "嵯峨" + ], + [ + "鞭便刃", + "鞭刃" + ], + [ + "险星", + "陨星" + ], + [ + "赫黑大", + "赫默" + ], + [ + "雪难", + "雪雉" + ], + [ + "狮竭", + "狮蝎" + ], + [ + "第草", + "苇草" + ], + [ + "漂冬", + "凛冬" + ], + [ + "韦草", + "苇草" ] ] }, @@ -4370,22 +4430,6 @@ 100 ] }, - "CopilotFormation-OperNameUpperFlag": { - "roi": [ - 370, - 310, - 910, - 40 - ] - }, - "CopilotFormation-OperNameLowerFlag": { - "roi": [ - 370, - 590, - 910, - 40 - ] - }, "BattleQuickFormation": { "action": "ClickSelf", "roi": [ @@ -4421,14 +4465,24 @@ ], "rearDelay": 1000 }, + "BattleQuickFormation-OperNameFlag": { + "templThreshold": 0.99, + "roi": [ + 370, + 300, + 910, + 330 + ] + }, "BattleQuickFormationOCR": { "algorithm": "OcrDetect", + "fullMatch": true, "text": [], "roi": [ - 300, - 240, - 980, - 470 + 10, + -10, + 117, + 22 ], "rearDelay": 100 }, diff --git a/resource/template/BattleQuickFormation-OperNameFlag.png b/resource/template/BattleQuickFormation-OperNameFlag.png new file mode 100644 index 0000000000..0382f2af48 Binary files /dev/null and b/resource/template/BattleQuickFormation-OperNameFlag.png differ diff --git a/src/MeoAssistant/BattleFormationTask.cpp b/src/MeoAssistant/BattleFormationTask.cpp index 9940076c24..a0319b870e 100644 --- a/src/MeoAssistant/BattleFormationTask.cpp +++ b/src/MeoAssistant/BattleFormationTask.cpp @@ -3,7 +3,7 @@ #include "Resource.h" #include "Controller.h" #include "ProcessTask.h" -#include "OcrImageAnalyzer.h" +#include "OcrWithFlagTemplImageAnalyzer.h" void asst::BattleFormationTask::set_stage_name(std::string name) { @@ -54,12 +54,10 @@ bool asst::BattleFormationTask::enter_selection_page() bool asst::BattleFormationTask::select_opers_in_cur_page() { auto formation_task_ptr = Task.get("BattleQuickFormationOCR"); - OcrImageAnalyzer name_analyzer(m_ctrler->get_image()); - name_analyzer.set_task_info(formation_task_ptr); - name_analyzer.set_replace( - std::dynamic_pointer_cast( - Task.get("CharsNameOcrReplace")) - ->replace_map); + OcrWithFlagTemplImageAnalyzer name_analyzer(m_ctrler->get_image()); + auto& ocr_replace = std::dynamic_pointer_cast(Task.get("CharsNameOcrReplace"))->replace_map; + name_analyzer.set_task_info("BattleQuickFormation-OperNameFlag", "BattleQuickFormationOCR"); + name_analyzer.set_replace(ocr_replace); if (!name_analyzer.analyze()) { return false; } diff --git a/src/MeoAssistant/MeoAssistant.vcxproj b/src/MeoAssistant/MeoAssistant.vcxproj index b50956b13d..03ab638a22 100644 --- a/src/MeoAssistant/MeoAssistant.vcxproj +++ b/src/MeoAssistant/MeoAssistant.vcxproj @@ -35,6 +35,8 @@ + + @@ -110,6 +112,8 @@ + + diff --git a/src/MeoAssistant/MeoAssistant.vcxproj.filters b/src/MeoAssistant/MeoAssistant.vcxproj.filters index 26e0ed1b8d..60b590cbfb 100644 --- a/src/MeoAssistant/MeoAssistant.vcxproj.filters +++ b/src/MeoAssistant/MeoAssistant.vcxproj.filters @@ -324,6 +324,12 @@ 头文件\Resource + + 头文件\ImageAnalyzer\General + + + 头文件\ImageAnalyzer\General + @@ -545,6 +551,12 @@ 源文件\Resource + + 源文件\ImageAnalyzer\General + + + 源文件\ImageAnalyzer\General + diff --git a/src/MeoAssistant/OcrImageAnalyzer.h b/src/MeoAssistant/OcrImageAnalyzer.h index 45656f96d9..47671c9dc8 100644 --- a/src/MeoAssistant/OcrImageAnalyzer.h +++ b/src/MeoAssistant/OcrImageAnalyzer.h @@ -24,18 +24,20 @@ namespace asst void sort_result_by_score(); // 按分数排序,得分最高的在前面 void sort_result_by_required(); // 按传入的需求数组排序,传入的在前面结果接在前面 - void set_use_cache(bool is_use) noexcept; void set_required(std::vector required, bool full_match = false) noexcept; void set_replace(std::unordered_map replace) noexcept; + void set_task_info(std::shared_ptr task_ptr); void set_task_info(const std::string& task_name); - void set_region_of_appeared(Rect region) noexcept; + + virtual void set_use_cache(bool is_use) noexcept; + virtual void set_region_of_appeared(Rect region) noexcept; void set_pred(const TextRectProc& pred); - const std::vector& get_result() const noexcept; + virtual const std::vector& get_result() const noexcept; protected: - void set_task_info(OcrTaskInfo task_info) noexcept; + virtual void set_task_info(OcrTaskInfo task_info) noexcept; std::vector m_ocr_result; std::vector m_required; diff --git a/src/MeoAssistant/OcrWithFlagTemplImageAnalyzer.cpp b/src/MeoAssistant/OcrWithFlagTemplImageAnalyzer.cpp new file mode 100644 index 0000000000..ba6f83beac --- /dev/null +++ b/src/MeoAssistant/OcrWithFlagTemplImageAnalyzer.cpp @@ -0,0 +1,73 @@ +#include "OcrWithFlagTemplImageAnalyzer.h" + +#include "TaskData.h" + +asst::OcrWithFlagTemplImageAnalyzer::OcrWithFlagTemplImageAnalyzer(const cv::Mat image) + : OcrWithPreprocessImageAnalyzer(image), + m_multi_match_image_analyzer(image) +{} + +asst::OcrWithFlagTemplImageAnalyzer::OcrWithFlagTemplImageAnalyzer(const cv::Mat image, const Rect& roi) + : OcrWithPreprocessImageAnalyzer(image, roi), + m_multi_match_image_analyzer(image, roi) +{} + +void asst::OcrWithFlagTemplImageAnalyzer::set_image(const cv::Mat image) +{ + OcrWithPreprocessImageAnalyzer::set_image(image); + m_multi_match_image_analyzer.set_image(image); +} + +void asst::OcrWithFlagTemplImageAnalyzer::set_image(const cv::Mat image, const Rect& roi) +{ + OcrWithPreprocessImageAnalyzer::set_image(image, roi); + m_multi_match_image_analyzer.set_image(image, roi); +} + +void asst::OcrWithFlagTemplImageAnalyzer::set_roi(const Rect& roi) noexcept +{ + OcrWithPreprocessImageAnalyzer::set_roi(roi); + m_multi_match_image_analyzer.set_roi(roi); +} + +bool asst::OcrWithFlagTemplImageAnalyzer::analyze() +{ + m_all_result.clear(); + + if (!m_multi_match_image_analyzer.analyze()) { + return false; + } + for (const auto& templ_res : m_multi_match_image_analyzer.get_result()) { + Rect roi = templ_res.rect.move(m_flag_rect_move); + if (roi.x + roi.width >= WindowWidthDefault) { + continue; + } + set_roi(roi); + + if (OcrWithPreprocessImageAnalyzer::analyze()) { + m_all_result.insert(m_all_result.end(), + std::make_move_iterator(m_ocr_result.begin()), + std::make_move_iterator(m_ocr_result.end())); + } + } + + return !m_all_result.empty(); +} + +const std::vector& asst::OcrWithFlagTemplImageAnalyzer::get_result() const noexcept +{ + return m_all_result; +} + +void asst::OcrWithFlagTemplImageAnalyzer::set_task_info(std::string templ_task_name, std::string ocr_task_name) +{ + auto ocr_task_ptr = std::dynamic_pointer_cast(Task.get(ocr_task_name)); + OcrWithPreprocessImageAnalyzer::set_task_info(*ocr_task_ptr); + m_flag_rect_move = ocr_task_ptr->roi; + m_multi_match_image_analyzer.set_task_info(std::move(templ_task_name)); +} + +void asst::OcrWithFlagTemplImageAnalyzer::set_flag_rect_move(Rect flag_rect_move) +{ + m_flag_rect_move = std::move(flag_rect_move); +} diff --git a/src/MeoAssistant/OcrWithFlagTemplImageAnalyzer.h b/src/MeoAssistant/OcrWithFlagTemplImageAnalyzer.h new file mode 100644 index 0000000000..8fbcc50c30 --- /dev/null +++ b/src/MeoAssistant/OcrWithFlagTemplImageAnalyzer.h @@ -0,0 +1,31 @@ +#pragma once +#include "MultiMatchImageAnalyzer.h" +#include "OcrWithPreprocessImageAnalyzer.h" + +namespace asst +{ + class OcrWithFlagTemplImageAnalyzer : public OcrWithPreprocessImageAnalyzer + { + public: + OcrWithFlagTemplImageAnalyzer() = default; + OcrWithFlagTemplImageAnalyzer(const cv::Mat image); + OcrWithFlagTemplImageAnalyzer(const cv::Mat image, const Rect& roi); + virtual ~OcrWithFlagTemplImageAnalyzer() = default; + + virtual void set_image(const cv::Mat image); + virtual void set_image(const cv::Mat image, const Rect& roi); + virtual void set_roi(const Rect& roi) noexcept; + + virtual bool analyze() override; + + virtual const std::vector& get_result() const noexcept override; + + void set_task_info(std::string templ_task_name, std::string ocr_task_name); + void set_flag_rect_move(Rect flag_rect_move); + + protected: + MultiMatchImageAnalyzer m_multi_match_image_analyzer; + Rect m_flag_rect_move; + std::vector m_all_result; + }; +} diff --git a/src/MeoAssistant/OcrWithPreprocessImageAnalyzer.cpp b/src/MeoAssistant/OcrWithPreprocessImageAnalyzer.cpp new file mode 100644 index 0000000000..05287a07b6 --- /dev/null +++ b/src/MeoAssistant/OcrWithPreprocessImageAnalyzer.cpp @@ -0,0 +1,59 @@ +#include "OcrWithPreprocessImageAnalyzer.h" + +#include "AsstUtils.hpp" + +bool asst::OcrWithPreprocessImageAnalyzer::analyze() +{ + cv::Mat img_roi = m_image(utils::make_rect(m_roi)); + cv::Mat img_roi_gray; + cv::cvtColor(img_roi, img_roi_gray, cv::COLOR_BGR2GRAY); + cv::Mat bin; + cv::inRange(img_roi_gray, m_threshold_lower, m_threshold_upper, bin); + cv::Rect bounding_rect = cv::boundingRect(bin); + bounding_rect.x += m_roi.x; + bounding_rect.y += m_roi.y; + Rect new_roi = utils::make_rect(bounding_rect); + + // todo: split + + if (m_expansion) { + new_roi.x -= m_expansion; + new_roi.y -= m_expansion; + new_roi.width += 2 * m_expansion; + new_roi.height += 2 * m_expansion; + } + OcrImageAnalyzer::set_roi(new_roi); +#ifdef ASST_DEBUG + cv::rectangle(m_image_draw, utils::make_rect(new_roi), cv::Scalar(0, 0, 255), 1); +#endif // ASST_DEBUG + + + return OcrImageAnalyzer::analyze(); +} + +void asst::OcrWithPreprocessImageAnalyzer::set_threshold(int lower, int upper) +{ + m_threshold_lower = lower; + m_threshold_upper = upper; +} + +void asst::OcrWithPreprocessImageAnalyzer::set_split(bool split) +{ + m_split = split; +} + +void asst::OcrWithPreprocessImageAnalyzer::set_expansion(int expansion) +{ + m_expansion = expansion; +} + +void asst::OcrWithPreprocessImageAnalyzer::set_task_info(OcrTaskInfo task_info) noexcept +{ + m_required = std::move(task_info.text); + m_full_match = task_info.full_match; + m_replace = std::move(task_info.replace_map); + + set_roi(task_info.roi); + m_use_cache = true; + m_without_det = true; +} diff --git a/src/MeoAssistant/OcrWithPreprocessImageAnalyzer.h b/src/MeoAssistant/OcrWithPreprocessImageAnalyzer.h new file mode 100644 index 0000000000..3863fa4b58 --- /dev/null +++ b/src/MeoAssistant/OcrWithPreprocessImageAnalyzer.h @@ -0,0 +1,30 @@ +#pragma once +#include "OcrImageAnalyzer.h" + +namespace asst +{ + class OcrWithPreprocessImageAnalyzer : public OcrImageAnalyzer + { + public: + using OcrImageAnalyzer::OcrImageAnalyzer; + virtual ~OcrWithPreprocessImageAnalyzer() noexcept = default; + + virtual bool analyze() override; + + void set_threshold(int lower, int upper = 255); + void set_split(bool split); + void set_expansion(int expansion); + + protected: + virtual void set_task_info(OcrTaskInfo task_info) noexcept override; + + int m_threshold_lower = 140; + int m_threshold_upper = 255; + bool m_split = false; + int m_expansion = 2; + + private: + virtual void set_use_cache(bool is_use) noexcept override { std::ignore = is_use; } + virtual void set_region_of_appeared(Rect region) noexcept override { std::ignore = region; } + }; +}