perf.优化自动编队干员名的检测算法

This commit is contained in:
MistEO
2022-05-27 01:16:51 +08:00
parent 8be3968ccb
commit 05abae1f31
10 changed files with 294 additions and 31 deletions

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

View File

@@ -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<OcrTaskInfo>(
Task.get("CharsNameOcrReplace"))
->replace_map);
OcrWithFlagTemplImageAnalyzer name_analyzer(m_ctrler->get_image());
auto& ocr_replace = std::dynamic_pointer_cast<OcrTaskInfo>(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;
}

View File

@@ -35,6 +35,8 @@
<ClInclude Include="FightTask.h" />
<ClInclude Include="InfrastTask.h" />
<ClInclude Include="MallTask.h" />
<ClInclude Include="OcrWithFlagTemplImageAnalyzer.h" />
<ClInclude Include="OcrWithPreprocessImageAnalyzer.h" />
<ClInclude Include="PackageTask.h" />
<ClInclude Include="RecruitTask.h" />
<ClInclude Include="ReplenishOriginiumShardTaskPlugin.h" />
@@ -110,6 +112,8 @@
<ClCompile Include="FightTask.cpp" />
<ClCompile Include="InfrastTask.cpp" />
<ClCompile Include="MallTask.cpp" />
<ClCompile Include="OcrWithFlagTemplImageAnalyzer.cpp" />
<ClCompile Include="OcrWithPreprocessImageAnalyzer.cpp" />
<ClCompile Include="PackageTask.cpp" />
<ClCompile Include="RecruitTask.cpp" />
<ClCompile Include="ReplenishOriginiumShardTaskPlugin.cpp" />

View File

@@ -324,6 +324,12 @@
<ClInclude Include="StageDropsConfiger.h">
<Filter>头文件\Resource</Filter>
</ClInclude>
<ClInclude Include="OcrWithPreprocessImageAnalyzer.h">
<Filter>头文件\ImageAnalyzer\General</Filter>
</ClInclude>
<ClInclude Include="OcrWithFlagTemplImageAnalyzer.h">
<Filter>头文件\ImageAnalyzer\General</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Controller.cpp">
@@ -545,6 +551,12 @@
<ClCompile Include="StageDropsConfiger.cpp">
<Filter>源文件\Resource</Filter>
</ClCompile>
<ClCompile Include="OcrWithPreprocessImageAnalyzer.cpp">
<Filter>源文件\ImageAnalyzer\General</Filter>
</ClCompile>
<ClCompile Include="OcrWithFlagTemplImageAnalyzer.cpp">
<Filter>源文件\ImageAnalyzer\General</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\resource\config.json">

View File

@@ -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<std::string> required, bool full_match = false) noexcept;
void set_replace(std::unordered_map<std::string, std::string> replace) noexcept;
void set_task_info(std::shared_ptr<TaskInfo> 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<TextRect>& get_result() const noexcept;
virtual const std::vector<TextRect>& get_result() const noexcept;
protected:
void set_task_info(OcrTaskInfo task_info) noexcept;
virtual void set_task_info(OcrTaskInfo task_info) noexcept;
std::vector<TextRect> m_ocr_result;
std::vector<std::string> m_required;

View File

@@ -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::TextRect>& 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<OcrTaskInfo>(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);
}

View File

@@ -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<TextRect>& 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<TextRect> m_all_result;
};
}

View File

@@ -0,0 +1,59 @@
#include "OcrWithPreprocessImageAnalyzer.h"
#include "AsstUtils.hpp"
bool asst::OcrWithPreprocessImageAnalyzer::analyze()
{
cv::Mat img_roi = m_image(utils::make_rect<cv::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<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<cv::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;
}

View File

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