refactor: 干员名识别封装

This commit is contained in:
status102
2025-05-23 13:14:07 +08:00
parent 4c9a19b81a
commit e23c362cf3
6 changed files with 98 additions and 39 deletions

View File

@@ -3606,10 +3606,10 @@
"bin_expansion",
"trim_threshold_low",
"trim_threshold_high",
"左侧收缩时检测图的底部收缩",
"左侧收缩时检测图的底部屏蔽高度",
"左侧收缩时连续n像素低于bin_thresh"
],
"specialParams": [140, 2, 0, 0, -3, 10]
"specialParams": [140, 2, 0, 0, 3, 10]
},
"BattleQuickFormationSkill1": {
"algorithm": "JustReturn",

View File

@@ -297,6 +297,7 @@
<ClInclude Include="Vision\FeatureMatcher.h" />
<ClInclude Include="Utils\LibraryHolder.hpp" />
<ClInclude Include="Vision\Battle\SupportListAnalyzer.h" />
<ClInclude Include="Vision\Miscellaneous\OperNameAnalyzer.h" />
<ClInclude Include="Vision\Roguelike\RoguelikeParameterAnalyzer.h" />
<ClInclude Include="Vision\VisionHelper.h" />
<ClInclude Include="Vision\Battle\BattleFormationAnalyzer.h" />
@@ -492,6 +493,7 @@
<ClCompile Include="Vision\Battle\SupportListAnalyzer.cpp" />
<ClCompile Include="Vision\Config\FeatureMatcherConfig.cpp" />
<ClCompile Include="Vision\FeatureMatcher.cpp" />
<ClCompile Include="Vision\Miscellaneous\OperNameAnalyzer.cpp" />
<ClCompile Include="Vision\Roguelike\RoguelikeParameterAnalyzer.cpp" />
<ClCompile Include="Vision\VisionHelper.cpp" />
<ClCompile Include="Vision\Battle\BattleFormationAnalyzer.cpp" />

View File

@@ -1334,6 +1334,9 @@
<ClInclude Include="Task\Roguelike\RoguelikeInputSeedTaskPlugin.h">
<Filter>Source\Task\Roguelike</Filter>
</ClInclude>
<ClInclude Include="Vision\Miscellaneous\OperNameAnalyzer.h">
<Filter>Source\Vision\Miscellaneous</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Vision\VisionHelper.cpp">
@@ -1851,6 +1854,9 @@
<ClCompile Include="Task\Roguelike\RoguelikeInputSeedTaskPlugin.cpp">
<Filter>Source\Task\Roguelike</Filter>
</ClCompile>
<ClCompile Include="Vision\Miscellaneous\OperNameAnalyzer.cpp">
<Filter>Source\Vision\Miscellaneous</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Natvis Include="meojson.natvis" />

View File

@@ -12,6 +12,7 @@
#include "UseSupportUnitTaskPlugin.h"
#include "Utils/ImageIo.hpp"
#include "Utils/Logger.hpp"
#include "Vision/Miscellaneous/OperNameAnalyzer.h"
#include "Vision/MultiMatcher.h"
#include "Vision/RegionOCRer.h"
@@ -353,7 +354,7 @@ std::vector<asst::BattleFormationTask::QuickFormationOper>
{
const auto& ocr_replace = Task.get<OcrTaskInfo>("CharsNameOcrReplace");
std::vector<asst::BattleFormationTask::QuickFormationOper> opers_result;
cv::Mat select, ocr, gray, bin;
cv::Mat select;
for (int i = 0; i < 8; ++i) {
std::string task_name = "BattleQuickFormation-OperNameFlag" + std::to_string(i);
@@ -364,46 +365,14 @@ std::vector<asst::BattleFormationTask::QuickFormationOper>
continue;
}
for (const auto& flag : multi.get_result()) {
auto roi = flag.rect.move(ocr_task->rect_move);
if (roi.x < 0) {
roi.x = 0;
roi.width = roi.width + roi.x;
}
if (roi.y < 0) {
roi.y = 0;
roi.height = roi.height + roi.y;
}
if (roi.x + roi.width > image.cols) {
roi.width = image.cols - roi.x;
}
if (roi.y + roi.height > image.rows) {
roi.height = image.rows - roi.y;
}
ocr = make_roi(image, roi);
cv::cvtColor(ocr, gray, cv::COLOR_BGR2GRAY);
cv::inRange(gray, ocr_task->special_params[0], 255, bin);
for (int r = bin.cols - 1; r >= 0; --r) {
if (cv::hasNonZero(bin.col(r))) { // 右边界向左收缩
bin = bin.adjustROI(0, 0, 0, -(bin.cols - r - 1));
break;
}
}
bin = bin.adjustROI(0, ocr_task->special_params[4], 0, 0); // 底部收缩排除白线
int width = ocr_task->special_params[5];
for (int r = bin.cols - width - 1; r >= 0; --r) {
if (!cv::hasNonZero(bin.colRange(r, r + width))) { // 左边界排除无文字区域
ocr = ocr.adjustROI(0, 0, -r - 3, 0);
break;
}
}
RegionOCRer region(ocr);
OperNameAnalyzer region(image);
region.set_task_info(ocr_task);
region.set_roi(asst::Rect(0, 0, ocr.cols, ocr.rows));
region.set_roi(flag.rect.move(ocr_task->rect_move));
region.set_bin_threshold(ocr_task->special_params[0]);
region.set_bin_expansion(ocr_task->special_params[1]);
region.set_bin_trim_threshold(ocr_task->special_params[2], ocr_task->special_params[3]);
region.set_bottom_line_height(ocr_task->special_params[4]);
region.set_width_threshold(ocr_task->special_params[5]);
region.set_replace(ocr_replace->replace_map, ocr_replace->replace_full);
region.set_use_raw(true);
if (!region.analyze()) [[unlikely]] {

View File

@@ -0,0 +1,40 @@
#include "OperNameAnalyzer.h"
#include "Utils/NoWarningCV.h"
#include "Vision/RegionOCRer.h"
asst::OperNameAnalyzer::ResultOpt asst::OperNameAnalyzer::analyze() const
{
cv::Mat gray, bin;
cv::Mat ocr = make_roi(m_image, m_roi);
cv::cvtColor(ocr, gray, cv::COLOR_BGR2GRAY);
cv::inRange(gray, m_params.bin_threshold_lower, m_params.bin_threshold_upper, bin);
for (int r = bin.cols - 1; r >= 0; --r) {
if (cv::hasNonZero(bin.col(r))) { // 右边界向左收缩
bin = bin.adjustROI(0, 0, 0, -(bin.cols - r - 1));
break;
}
}
bin = bin.adjustROI(0, -m_bottom_line_height, 0, 0); // 底部收缩排除白线
int move = 0;
for (int r = bin.cols - m_width_threshold - 1; r >= 0; --r) {
if (!cv::hasNonZero(bin.colRange(r, r + m_width_threshold))) { // 左边界排除无文字区域
move = r + m_width_threshold - 3;
ocr = ocr.adjustROI(0, 0, -move, 0);
break;
}
}
RegionOCRer region(ocr);
region.set_params(m_params);
region.set_use_raw(true);
if (region.analyze()) {
m_result = region.get_result();
m_result.rect.x += move; // 修正偏移
m_result.rect = m_roi.move(m_result.rect);
return m_result;
}
return std::nullopt;
}

View File

@@ -0,0 +1,42 @@
#pragma once
#include <optional>
#include "Vision/Config/OCRerConfig.h"
#include "Vision/VisionHelper.h"
#include "Vision/OCRer.h"
namespace asst
{
class OperNameAnalyzer : public VisionHelper, public OCRerConfig
{
public:
using Result = OCRer::Result;
using ResultOpt = std::optional<Result>;
public:
using VisionHelper::VisionHelper;
virtual ~OperNameAnalyzer() override = default;
ResultOpt analyze() const;
void set_use_raw(bool use_raw) { m_use_raw = use_raw; }
void set_bottom_line_height(int height) { m_bottom_line_height = height; }
void set_width_threshold(int threshold) { m_width_threshold = threshold; }
// FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉
const auto& get_result() const noexcept { return m_result; }
protected:
using OCRerConfig::set_without_det;
virtual void _set_roi(const Rect& roi) override { set_roi(roi); }
private:
// FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉
mutable Result m_result;
bool m_use_raw = true;
int m_bottom_line_height = 3; // 底部线条高度
int m_width_threshold = 5; // 宽度阈值
};
}; // namespace asst