feat.完成基建设施的识别
@@ -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
|
||||
}
|
||||
}
|
||||
BIN
resource/template/ControlCenter.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
resource/template/ControlCenterMini.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 26 KiB |
BIN
resource/template/Reception.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
resource/template/ReceptionMini.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 24 KiB |
@@ -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())
|
||||
|
||||
@@ -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<InfrastDormTask>(task_callback, (void*)this);
|
||||
auto shift_task_ptr = std::make_shared<InfrastEnterFacilityTask>(task_callback, (void*)this);
|
||||
//shift_task_ptr->set_facility("Mfg");
|
||||
//shift_task_ptr->set_product("CombatRecord");
|
||||
shift_task_ptr->set_task_chain(DebugTaskChain);
|
||||
|
||||
15
src/MeoAssistance/InfrastEnterFacilityTask.cpp
Normal file
@@ -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;
|
||||
}
|
||||
18
src/MeoAssistance/InfrastEnterFacilityTask.h
Normal file
@@ -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<std::string> enter_order) noexcept {
|
||||
m_enter_order = std::move(enter_order);
|
||||
}
|
||||
private:
|
||||
std::vector<std::string> m_enter_order;
|
||||
};
|
||||
}
|
||||
86
src/MeoAssistance/InfrastFacilityImageAnalyzer.cpp
Normal file
@@ -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<std::string, std::string>
|
||||
facility_task_name = {
|
||||
{ "Dorm", "InfrastDorm" },
|
||||
{ "ControlCenter", "InfrastControlCenter" },
|
||||
{ "Mfg", "InfrastMfg" },
|
||||
{ "Trade", "InfrastTrade" },
|
||||
{ "Power", "InfrastPower" },
|
||||
{ "Office", "InfrastOffice" },
|
||||
{ "Reception", "InfrastReception" }
|
||||
};
|
||||
// 因为基建的缩放是不确定的,有可能是正常大小,也可能是最小化的
|
||||
// 所以对每种情况都进行一下识别,取其中得分最高的
|
||||
const static std::vector<std::string> 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<MatchTaskInfo>(
|
||||
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<MatchRect> 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<cv::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;
|
||||
}
|
||||
26
src/MeoAssistance/InfrastFacilityImageAnalyzer.h
Normal file
@@ -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<std::string, std::vector<MatchRect>> m_result;
|
||||
};
|
||||
}
|
||||
@@ -26,6 +26,8 @@
|
||||
<ClInclude Include="CreditShoppingTask.h" />
|
||||
<ClInclude Include="InfrastConfiger.h" />
|
||||
<ClInclude Include="InfrastDormTask.h" />
|
||||
<ClInclude Include="InfrastEnterFacilityTask.h" />
|
||||
<ClInclude Include="InfrastFacilityImageAnalyzer.h" />
|
||||
<ClInclude Include="InfrastMoodImageAnalyzer.h" />
|
||||
<ClInclude Include="InfrastShiftTask.h" />
|
||||
<ClInclude Include="InfrastSkillsImageAnalyzer.h" />
|
||||
@@ -60,6 +62,8 @@
|
||||
<ClCompile Include="CreditShoppingTask.cpp" />
|
||||
<ClCompile Include="InfrastConfiger.cpp" />
|
||||
<ClCompile Include="InfrastDormTask.cpp" />
|
||||
<ClCompile Include="InfrastEnterFacilityTask.cpp" />
|
||||
<ClCompile Include="InfrastFacilityImageAnalyzer.cpp" />
|
||||
<ClCompile Include="InfrastMoodImageAnalyzer.cpp" />
|
||||
<ClCompile Include="InfrastShiftTask.cpp" />
|
||||
<ClCompile Include="InfrastSkillsImageAnalyzer.cpp" />
|
||||
|
||||
@@ -174,6 +174,12 @@
|
||||
<ClInclude Include="InfrastMoodImageAnalyzer.h">
|
||||
<Filter>头文件\ImageAnalyzer\Infrast</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="InfrastEnterFacilityTask.h">
|
||||
<Filter>头文件\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="InfrastFacilityImageAnalyzer.h">
|
||||
<Filter>头文件\ImageAnalyzer\Infrast</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Controller.cpp">
|
||||
@@ -275,6 +281,12 @@
|
||||
<ClCompile Include="InfrastMoodImageAnalyzer.cpp">
|
||||
<Filter>源文件\ImageAnalyzer\Infrast</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="InfrastEnterFacilityTask.cpp">
|
||||
<Filter>源文件\Task</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="InfrastFacilityImageAnalyzer.cpp">
|
||||
<Filter>源文件\ImageAnalyzer\Infrast</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\resource\config.json">
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||