diff --git a/resource/tasks.json b/resource/tasks.json index 47b199e902..09043947f0 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -933,5 +933,71 @@ 85, 4 ] + }, + "InfrastMfg": { + "template": "Manufacturing.png", + "maskRange": [ 1, 255 ] + }, + "InfrastMfgMini": { + "template": "ManufacturingMini.png", + "maskRange": [ 1, 255 ] + }, + "InfrastTrade": { + "template": "Trade.png", + "maskRange": [ 1, 255 ] + }, + "InfrastTradeMini": { + "template": "TradeMini.png", + "maskRange": [ 1, 255 ] + }, + "InfrastPower": { + "template": "Power.png", + "maskRange": [ 1, 255 ], + "templThreshold": 0.95 + }, + "InfrastPowerMini": { + "template": "PowerMini.png", + "maskRange": [ 1, 255 ], + "templThreshold": 0.95 + }, + "InfrastDorm": { + "template": "Dorm.png", + "maskRange": [ 1, 255 ], + "templThreshold": 0.95 + }, + "InfrastDormMini": { + "template": "DormMini.png", + "maskRange": [ 1, 255 ], + "templThreshold": 0.95 + }, + "InfrastOffice": { + "template": "Office.png", + "maskRange": [ 1, 255 ], + "templThreshold": 0.95 + }, + "InfrastOfficeMini": { + "template": "OfficeMini.png", + "maskRange": [ 1, 255 ], + "templThreshold": 0.95 + }, + "InfrastReception": { + "template": "Reception.png", + "maskRange": [ 1, 255 ], + "templThreshold": 0.95 + }, + "InfrastReceptionMini": { + "template": "ReceptionMini.png", + "maskRange": [ 1, 255 ], + "templThreshold": 0.95 + }, + "InfrastControlCenter": { + "template": "ControlCenter.png", + "maskRange": [ 1, 255 ], + "templThreshold": 0.95 + }, + "InfrastControlCenterMini": { + "template": "ControlCenterMini.png", + "maskRange": [ 1, 255 ], + "templThreshold": 0.95 } } \ No newline at end of file diff --git a/resource/template/ControlCenter.png b/resource/template/ControlCenter.png new file mode 100644 index 0000000000..547ea54687 Binary files /dev/null and b/resource/template/ControlCenter.png differ diff --git a/resource/template/ControlCenterMini.png b/resource/template/ControlCenterMini.png new file mode 100644 index 0000000000..f8db28c5e9 Binary files /dev/null and b/resource/template/ControlCenterMini.png differ diff --git a/resource/template/Dorm.png b/resource/template/Dorm.png index e1af117350..ea3acdc669 100644 Binary files a/resource/template/Dorm.png and b/resource/template/Dorm.png differ diff --git a/resource/template/DormMini.png b/resource/template/DormMini.png index e740c20976..125a97887c 100644 Binary files a/resource/template/DormMini.png and b/resource/template/DormMini.png differ diff --git a/resource/template/Manufacturing.png b/resource/template/Manufacturing.png index 6cb54f0061..07c22689da 100644 Binary files a/resource/template/Manufacturing.png and b/resource/template/Manufacturing.png differ diff --git a/resource/template/ManufacturingMini.png b/resource/template/ManufacturingMini.png index 0e062736b9..71d00cc1af 100644 Binary files a/resource/template/ManufacturingMini.png and b/resource/template/ManufacturingMini.png differ diff --git a/resource/template/Office.png b/resource/template/Office.png index 9ce0c80357..4d98e6d210 100644 Binary files a/resource/template/Office.png and b/resource/template/Office.png differ diff --git a/resource/template/OfficeMini.png b/resource/template/OfficeMini.png index 60a8a50164..599d6f905c 100644 Binary files a/resource/template/OfficeMini.png and b/resource/template/OfficeMini.png differ diff --git a/resource/template/Power.png b/resource/template/Power.png index c04f3d78e1..e461050d3e 100644 Binary files a/resource/template/Power.png and b/resource/template/Power.png differ diff --git a/resource/template/PowerMini.png b/resource/template/PowerMini.png index a2f4f02e62..b58e075d2a 100644 Binary files a/resource/template/PowerMini.png and b/resource/template/PowerMini.png differ diff --git a/resource/template/Reception.png b/resource/template/Reception.png new file mode 100644 index 0000000000..c16f98beda Binary files /dev/null and b/resource/template/Reception.png differ diff --git a/resource/template/ReceptionMini.png b/resource/template/ReceptionMini.png new file mode 100644 index 0000000000..9ae90b86a9 Binary files /dev/null and b/resource/template/ReceptionMini.png differ diff --git a/resource/template/Trade.png b/resource/template/Trade.png index d17a87a9c0..b593ff7963 100644 Binary files a/resource/template/Trade.png and b/resource/template/Trade.png differ diff --git a/resource/template/TradeMini.png b/resource/template/TradeMini.png index 0c2f88ca87..2a3ff85097 100644 Binary files a/resource/template/TradeMini.png and b/resource/template/TradeMini.png differ diff --git a/src/MeoAssistance/AbstractImageAnalyzer.cpp b/src/MeoAssistance/AbstractImageAnalyzer.cpp index 0e19cf1528..8f2002bca3 100644 --- a/src/MeoAssistance/AbstractImageAnalyzer.cpp +++ b/src/MeoAssistance/AbstractImageAnalyzer.cpp @@ -4,6 +4,7 @@ asst::AbstractImageAnalyzer::AbstractImageAnalyzer(const cv::Mat& image) : m_image(image) + , m_roi(empty_rect_to_full(Rect(), image)) #ifdef LOG_TRACE , m_image_draw(image.clone()) diff --git a/src/MeoAssistance/Assistance.cpp b/src/MeoAssistance/Assistance.cpp index 046e0b740a..3774d3965e 100644 --- a/src/MeoAssistance/Assistance.cpp +++ b/src/MeoAssistance/Assistance.cpp @@ -17,6 +17,7 @@ #include "CreditShoppingTask.h" #include "InfrastShiftTask.h" #include "InfrastDormTask.h" +#include "InfrastEnterFacilityTask.h" using namespace asst; @@ -242,7 +243,7 @@ bool Assistance::start_debug_task() //} { constexpr static const char* DebugTaskChain = "Debug"; - auto shift_task_ptr = std::make_shared(task_callback, (void*)this); + auto shift_task_ptr = std::make_shared(task_callback, (void*)this); //shift_task_ptr->set_facility("Mfg"); //shift_task_ptr->set_product("CombatRecord"); shift_task_ptr->set_task_chain(DebugTaskChain); diff --git a/src/MeoAssistance/InfrastEnterFacilityTask.cpp b/src/MeoAssistance/InfrastEnterFacilityTask.cpp new file mode 100644 index 0000000000..c8a883d81a --- /dev/null +++ b/src/MeoAssistance/InfrastEnterFacilityTask.cpp @@ -0,0 +1,15 @@ +#include "InfrastEnterFacilityTask.h" + +#include "InfrastFacilityImageAnalyzer.h" +#include "Resource.h" +#include "Controller.h" + +bool asst::InfrastEnterFacilityTask::run() +{ + const auto& image = ctrler.get_image(); + + InfrastFacilityImageAnalyzer analyzer(image); + analyzer.analyze(); + + return false; +} \ No newline at end of file diff --git a/src/MeoAssistance/InfrastEnterFacilityTask.h b/src/MeoAssistance/InfrastEnterFacilityTask.h new file mode 100644 index 0000000000..9b2e45c8c2 --- /dev/null +++ b/src/MeoAssistance/InfrastEnterFacilityTask.h @@ -0,0 +1,18 @@ +#pragma once +#include "AbstractTask.h" + +namespace asst { + class InfrastEnterFacilityTask : public AbstractTask + { + public: + using AbstractTask::AbstractTask; + virtual ~InfrastEnterFacilityTask() = default; + virtual bool run() override; + + void set_enter_order(std::vector enter_order) noexcept { + m_enter_order = std::move(enter_order); + } + private: + std::vector m_enter_order; + }; +} diff --git a/src/MeoAssistance/InfrastFacilityImageAnalyzer.cpp b/src/MeoAssistance/InfrastFacilityImageAnalyzer.cpp new file mode 100644 index 0000000000..229c7ac1cf --- /dev/null +++ b/src/MeoAssistance/InfrastFacilityImageAnalyzer.cpp @@ -0,0 +1,86 @@ +#include "InfrastFacilityImageAnalyzer.h" + +#include "Resource.h" +#include "MultiMatchImageAnalyzer.h" +#include "AsstUtils.hpp" + +bool asst::InfrastFacilityImageAnalyzer::analyze() +{ + const static std::unordered_map + facility_task_name = { + { "Dorm", "InfrastDorm" }, + { "ControlCenter", "InfrastControlCenter" }, + { "Mfg", "InfrastMfg" }, + { "Trade", "InfrastTrade" }, + { "Power", "InfrastPower" }, + { "Office", "InfrastOffice" }, + { "Reception", "InfrastReception" } + }; + // 因为基建的缩放是不确定的,有可能是正常大小,也可能是最小化的 + // 所以对每种情况都进行一下识别,取其中得分最高的 + const static std::vector task_name_suffix = { "", "Mini" }; + + MultiMatchImageAnalyzer mm_analyzer(m_image); + + auto task_analyze = [&](const std::string& task_name) -> bool { + const auto task_ptr = std::dynamic_pointer_cast( + resource.task().task_ptr(task_name)); + mm_analyzer.set_templ_name(task_ptr->templ_name); + mm_analyzer.set_threshold(task_ptr->templ_threshold); + mm_analyzer.set_mask_range(task_ptr->mask_range); + + return mm_analyzer.analyze(); + }; + + int cor_suffix_index = -1; + + for (const auto& [key, task_name] : facility_task_name) { + std::vector cur_facility_result; + // 已知基建缩放状态的时候,只识别这个缩放状态下的就行了 + // 否则识别所有状态,直到找出正确的当前缩放状态 + if (cor_suffix_index >= 0) { + if (!task_analyze(task_name + task_name_suffix.at(cor_suffix_index))) { + continue; + } + mm_analyzer.sort_result(); + cur_facility_result = mm_analyzer.get_result(); + } + else { + double max_score = 0; + for (size_t i = 0; i != task_name_suffix.size(); ++i) { + if (!task_analyze(task_name + task_name_suffix.at(i))) { + continue; + } + + const auto& cur_res = mm_analyzer.get_result(); + auto cur_max_iter = std::max_element(cur_res.cbegin(), cur_res.cend(), + [](const MatchRect& lhs, const MatchRect& rhs) -> bool { + return lhs.score < rhs.score; + }); + if (cur_max_iter == cur_res.cend()) { + continue; + } + if (double cur_score = cur_max_iter->score; + max_score < cur_score) { + mm_analyzer.sort_result(); + max_score = cur_score; + cur_facility_result = cur_res; + cor_suffix_index = i; + } + } + } +#ifdef LOG_TRACE + cv::RNG rng(time(0)); + cv::Scalar rand_color(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); + int index = 0; + for (const MatchRect& mr : cur_facility_result) { + cv::rectangle(m_image_draw, utils::make_rect(mr.rect), rand_color, 2); + cv::Point text_point(mr.rect.x + 2, mr.rect.y + mr.rect.height / 2); + cv::putText(m_image_draw, task_name + std::to_string(index++), text_point, 1, 1, cv::Scalar(0, 0, 255), 1); + } +#endif + m_result.emplace(key, std::move(cur_facility_result)); + } + + return true; +} \ No newline at end of file diff --git a/src/MeoAssistance/InfrastFacilityImageAnalyzer.h b/src/MeoAssistance/InfrastFacilityImageAnalyzer.h new file mode 100644 index 0000000000..edc6579810 --- /dev/null +++ b/src/MeoAssistance/InfrastFacilityImageAnalyzer.h @@ -0,0 +1,26 @@ +#pragma once +#include "AbstractImageAnalyzer.h" + +namespace asst { + class InfrastFacilityImageAnalyzer final : public AbstractImageAnalyzer + { + public: + using AbstractImageAnalyzer::AbstractImageAnalyzer; + virtual ~InfrastFacilityImageAnalyzer() = default; + InfrastFacilityImageAnalyzer(const cv::Mat& image, const Rect& roi) = delete; + + virtual bool analyze() override; + + private: + // 该分析器不支持外部设置ROI + virtual void set_roi(const Rect& roi) noexcept override { + AbstractImageAnalyzer::set_roi(roi); + } + virtual void set_image(const cv::Mat& image, const Rect& roi) { + AbstractImageAnalyzer::set_image(image, roi); + } + + // key:设施名,value:所有这种设施的当前Rect(例如所有制造站的位置) + std::unordered_map> m_result; + }; +} diff --git a/src/MeoAssistance/MeoAssistance.vcxproj b/src/MeoAssistance/MeoAssistance.vcxproj index 88f3471a86..cf2401f8c1 100644 --- a/src/MeoAssistance/MeoAssistance.vcxproj +++ b/src/MeoAssistance/MeoAssistance.vcxproj @@ -26,6 +26,8 @@ + + @@ -60,6 +62,8 @@ + + diff --git a/src/MeoAssistance/MeoAssistance.vcxproj.filters b/src/MeoAssistance/MeoAssistance.vcxproj.filters index d163c79265..643e27a2db 100644 --- a/src/MeoAssistance/MeoAssistance.vcxproj.filters +++ b/src/MeoAssistance/MeoAssistance.vcxproj.filters @@ -174,6 +174,12 @@ 头文件\ImageAnalyzer\Infrast + + 头文件\Task + + + 头文件\ImageAnalyzer\Infrast + @@ -275,6 +281,12 @@ 源文件\ImageAnalyzer\Infrast + + 源文件\Task + + + 源文件\ImageAnalyzer\Infrast + diff --git a/src/MeoAssistance/MultiMatchImageAnalyzer.h b/src/MeoAssistance/MultiMatchImageAnalyzer.h index 1cb5dace8d..31d588a3c8 100644 --- a/src/MeoAssistance/MultiMatchImageAnalyzer.h +++ b/src/MeoAssistance/MultiMatchImageAnalyzer.h @@ -11,7 +11,7 @@ namespace asst { virtual bool analyze() override; - void sort_result(); + void sort_result(); // 按位置排序,左上角的排在前面 void set_mask_range(int lower, int upper) { m_mask_range = std::make_pair(lower, upper); }