feat.完成基建设施的识别

This commit is contained in:
MistEO
2021-10-23 22:34:07 +08:00
parent ea70c4702a
commit 400a421677
24 changed files with 231 additions and 2 deletions

View File

@@ -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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -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())

View File

@@ -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);

View 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;
}

View 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;
};
}

View 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;
}

View 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;
};
}

View File

@@ -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" />

View File

@@ -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">

View File

@@ -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);
}