perf: 优化干员识别 flag 检测

This commit is contained in:
MistEO
2023-04-29 21:24:33 +08:00
parent 39ca6ce07b
commit 2b29dc7fa3
15 changed files with 97 additions and 80 deletions

View File

@@ -2323,30 +2323,6 @@
"[Uu]-[O0o]f{1,2}icial",
"U-Official"
],
[
"^4",
""
],
[
"^α",
""
],
[
"^-",
""
],
[
"—",
""
],
[
".*12F",
"12F"
],
[
"^_",
""
],
[
".*威龙陈",
"假日威龙陈"
@@ -9862,15 +9838,33 @@
20
]
},
"OperBoxFlagLV": {
"templThreshold": 0.6,
"OperBoxFlagRoleTopROI": {
"template": "empty.png",
"roi": [
40,
310,
1128,
327
0,
78,
1145,
50
]
},
"OperBoxFlagRoleBottomROI": {
"template": "empty.png",
"roi": [
0,
394,
1145,
50
]
},
"OperBoxFlagRole1": {},
"OperBoxFlagRole2": {},
"OperBoxFlagRole3": {},
"OperBoxFlagRole4": {},
"OperBoxFlagRole5": {},
"OperBoxFlagRole6": {},
"OperBoxFlagRole7": {},
"OperBoxFlagRole8": {},
"OperBoxFlagRole9": {},
"OperBoxFlagElite1": {
"doc": "精英一 模板"
},
@@ -9882,8 +9876,8 @@
"template": "empty.png",
"templThreshold": 0.9,
"roi": [
-7,
-52,
11,
171,
24,
35
]
@@ -9893,8 +9887,8 @@
"template": "empty.png",
"templThreshold": 0.85,
"roi": [
81,
-29,
99,
194,
24,
24
]
@@ -9905,16 +9899,14 @@
"OperBoxPotential4": {},
"OperBoxPotential5": {},
"OperBoxNameOCR": {
"algorithm": "OcrDetect",
"fullMatch": true,
"baseTask": "CharsNameOcrReplace",
"text": [],
"roi": [
5,
42,
105,
20
],
"postDelay": 100
4,
269,
122,
14
]
},
"OperBoxLevelOCR": {
"algorithm": "OcrDetect",
@@ -9922,12 +9914,11 @@
"isAscii": true,
"text": [],
"roi": [
-13,
7,
5,
230,
37,
23
],
"postDelay": 100
]
},
"RoguelikeRecruitSwipeMaxTime": {
"algorithm": "JustReturn",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -118,29 +118,5 @@ std::vector<BattlefieldDetector::OperatorResult> BattlefieldDetector::operator_a
all_results.emplace_back(std::move(box));
}
// NMS
constexpr double NmsThreshold = 0.7f;
std::sort(all_results.begin(), all_results.end(),
[](const OperatorResult& a, const OperatorResult& b) { return a.score > b.score; });
std::vector<OperatorResult> nms_results;
for (size_t i = 0; i < all_results.size(); ++i) {
const auto& box = all_results[i];
if (box.score < 0.1f) {
continue;
}
nms_results.emplace_back(box);
for (size_t j = i + 1; j < all_results.size(); ++j) {
auto& box2 = all_results[j];
if (box2.score < 0.1f) {
continue;
}
int iou_area = (make_rect<cv::Rect>(box.rect) & make_rect<cv::Rect>(box2.rect)).area();
if (iou_area > NmsThreshold * box2.rect.area()) {
box2.score = 0;
}
}
}
return nms_results;
return NMS(all_results);
}

View File

@@ -4,6 +4,7 @@
#include "Config/Miscellaneous/BattleDataConfig.h"
#include "Config/TaskData.h"
#include "Utils/ImageIo.hpp"
#include "Utils/Logger.hpp"
#include "Vision/BestMatcher.h"
#include "Vision/Matcher.h"
@@ -57,23 +58,44 @@ bool asst::OperBoxImageAnalyzer::analyzer_oper_box()
bool asst::OperBoxImageAnalyzer::opers_analyze()
{
const auto& ocr_replace = Task.get<OcrTaskInfo>("CharsNameOcrReplace");
TemplDetOCRer oper_name_analyzer(m_image);
oper_name_analyzer.set_task_info("OperBoxFlagLV", "OperBoxNameOCR");
oper_name_analyzer.set_replace(ocr_replace->replace_map, ocr_replace->replace_full);
oper_name_analyzer.set_bin_threshold(160);
oper_name_analyzer.set_bin_expansion(4);
oper_name_analyzer.set_bin_trim_threshold(4, 0);
const auto& all_opers = BattleData.get_all_oper_names();
oper_name_analyzer.set_required(std::vector(all_opers.begin(), all_opers.end()));
if (!oper_name_analyzer.analyze()) {
TemplDetOCRer::ResultsVec results;
Rect roi_top = Task.get("OperBoxFlagRoleTopROI")->roi;
Rect roi_bottom = Task.get("OperBoxFlagRoleBottomROI")->roi;
for (int i = 1; i < 10; ++i) {
oper_name_analyzer.set_task_info("OperBoxFlagRole" + std::to_string(i), "OperBoxNameOCR");
oper_name_analyzer.set_roi(roi_top);
auto top_result_opt = oper_name_analyzer.analyze();
if (top_result_opt) {
results.insert(results.end(), std::make_move_iterator(top_result_opt->begin()),
std::make_move_iterator(top_result_opt->end()));
}
oper_name_analyzer.set_roi(roi_bottom);
auto bottom_result_opt = oper_name_analyzer.analyze();
if (bottom_result_opt) {
results.insert(results.end(), std::make_move_iterator(bottom_result_opt->begin()),
std::make_move_iterator(bottom_result_opt->end()));
}
}
if (results.empty()) {
return false;
}
auto result_list = oper_name_analyzer.get_result();
sort_by_horizontal_(result_list);
results = NMS(results);
sort_by_horizontal_(results);
for (const auto& oper : result_list) {
for (const auto& oper : results) {
const Rect& flag_rect = oper.flag_rect;
const std::string& name = oper.text;
@@ -87,7 +109,7 @@ bool asst::OperBoxImageAnalyzer::opers_analyze()
#ifdef ASST_DEBUG
cv::rectangle(m_image_draw, make_rect<cv::Rect>(flag_rect), cv::Scalar(0, 255, 0), 1);
cv::putText(m_image_draw, std::to_string(oper.flag_score), cv::Point(flag_rect.x + 10, flag_rect.y),
cv::putText(m_image_draw, std::to_string(oper.flag_score), cv::Point(flag_rect.x, flag_rect.y - 10),
cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 255), 1);
cv::rectangle(m_image_draw, make_rect<cv::Rect>(oper.rect), cv::Scalar(0, 255, 0), 1);
#endif

View File

@@ -16,6 +16,7 @@ namespace asst
Rect rect;
bool own = false;
};
class OperBoxImageAnalyzer final : public VisionHelper
{
public:

View File

@@ -109,4 +109,31 @@ namespace asst
return lvalue < rvalue;
});
}
// Non-Maximum Suppression
template <typename ResultsVec>
inline static ResultsVec NMS(ResultsVec& results, double threshold = 0.7)
{
ranges::sort(results, [](const auto& a, const auto& b) { return a.score > b.score; });
ResultsVec nms_results;
for (size_t i = 0; i < results.size(); ++i) {
const auto& box = results[i];
if (box.score < 0.1f) {
continue;
}
nms_results.emplace_back(box);
for (size_t j = i + 1; j < results.size(); ++j) {
auto& box2 = results[j];
if (box2.score < 0.1f) {
continue;
}
int iou_area = (make_rect<cv::Rect>(box.rect) & make_rect<cv::Rect>(box2.rect)).area();
if (iou_area > threshold * box2.rect.area()) {
box2.score = 0;
}
}
}
return nms_results;
}
} // namespace asst