mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-18 10:10:45 +08:00
feat: 删去 CcoeffHSV, HSVCount 时的模板匹配采用 RGB 的 Ccoeff
CcoeffHSV 有致命缺陷: (0, 0, 0) 与 (179, 0, 0) 应为相似颜色,因为 Hue 是循环的 * feat: HSVCount & RGBCount 的返回结果为点积 为了尽量保证 0.8 的阈值 * workaround: HSVCount & RGBCount 时 maskRange 不再对模板匹配生效 否则数色时的模板匹配结果将不准确,之后可以分开 maskRange 和 colorRange, 后者的格式可以讨论后再做决定
This commit is contained in:
@@ -109,9 +109,10 @@ icon: material-symbols:task
|
||||
"method": "Ccoeff", // 可选项,模板匹配算法,可以是列表
|
||||
// 不填写时默认为 Ccoeff
|
||||
// - Ccoeff: 对应 cv::TM_CCOEFF_NORMED
|
||||
// - CcoeffHSV: 转换为 HSV 颜色空间后再进行 CCOEFF
|
||||
// - RGBCount: 先将待匹配区域和模板图片依据 maskRange 二值化,
|
||||
// 以 F1-score 为指标计算 RGB 颜色空间内的相似度
|
||||
// 以 F1-score 为指标计算 RGB 颜色空间内的相似度,
|
||||
// 再将结果与 Ccoeff 的结果点积
|
||||
// 总之是一个颜色敏感的模板匹配算法
|
||||
// - HSVCount: 类似 RGBCount,颜色空间换为 HSV
|
||||
|
||||
/* 以下字段仅当 algorithm 为 OcrDetect 时有效 */
|
||||
|
||||
@@ -9455,14 +9455,12 @@
|
||||
},
|
||||
"Sarkaz@Roguelike@StageFilterTruthCanCombine": {
|
||||
"action": "ClickSelf",
|
||||
"method": "CcoeffHSV",
|
||||
"templThreshold": 0.95,
|
||||
"roi": [750, 525, 188, 129],
|
||||
"next": ["Sarkaz@Roguelike@StageFilterTruthChooseCollection", "Sarkaz@Roguelike@StageFilterTruthConfirm"]
|
||||
},
|
||||
"Sarkaz@Roguelike@StageFilterTruthCannotCombine": {
|
||||
"action": "DoNothing",
|
||||
"method": "CcoeffHSV",
|
||||
"templThreshold": 0.95,
|
||||
"roi": [750, 525, 188, 129],
|
||||
"next": ["Sarkaz@Roguelike@StageFilterTruthLeave"]
|
||||
|
||||
@@ -361,7 +361,6 @@ namespace asst
|
||||
{
|
||||
Invalid = -1,
|
||||
Ccoeff = 0,
|
||||
CcoeffHSV,
|
||||
RGBCount,
|
||||
HSVCount,
|
||||
};
|
||||
@@ -370,8 +369,9 @@ namespace asst
|
||||
{
|
||||
utils::tolowers(method_str);
|
||||
static const std::unordered_map<std::string, MatchMethod> method_map = {
|
||||
{ "ccoeff", MatchMethod::Ccoeff }, { "ccoeffhsv", MatchMethod::CcoeffHSV },
|
||||
{ "rgbcount", MatchMethod::RGBCount }, { "hsvcount", MatchMethod::HSVCount },
|
||||
{ "ccoeff", MatchMethod::Ccoeff },
|
||||
{ "rgbcount", MatchMethod::RGBCount },
|
||||
{ "hsvcount", MatchMethod::HSVCount },
|
||||
};
|
||||
if (auto it = method_map.find(method_str); it != method_map.end()) {
|
||||
return it->second;
|
||||
@@ -384,7 +384,6 @@ namespace asst
|
||||
static const std::unordered_map<MatchMethod, std::string> method_map = {
|
||||
{ MatchMethod::Invalid, "Invalid" },
|
||||
{ MatchMethod::Ccoeff, "Ccoeff" },
|
||||
{ MatchMethod::CcoeffHSV, "CcoeffHSV" },
|
||||
{ MatchMethod::RGBCount, "RGBCount" },
|
||||
{ MatchMethod::HSVCount, "HSVCount" },
|
||||
};
|
||||
|
||||
@@ -96,13 +96,17 @@ std::vector<Matcher::RawResult> Matcher::preproc_and_match(const cv::Mat& image,
|
||||
cv::Mat matched;
|
||||
cv::Mat image_for_match;
|
||||
cv::Mat templ_for_match;
|
||||
if (method == MatchMethod::CcoeffHSV || method == MatchMethod::HSVCount) {
|
||||
cv::cvtColor(image, image_for_match, cv::COLOR_BGR2HSV);
|
||||
cv::cvtColor(templ, templ_for_match, cv::COLOR_BGR2HSV);
|
||||
cv::Mat image_for_count;
|
||||
cv::Mat templ_for_count;
|
||||
cv::cvtColor(image, image_for_match, cv::COLOR_BGR2RGB);
|
||||
cv::cvtColor(templ, templ_for_match, cv::COLOR_BGR2RGB);
|
||||
if (method == MatchMethod::HSVCount) {
|
||||
cv::cvtColor(image, image_for_count, cv::COLOR_BGR2HSV);
|
||||
cv::cvtColor(templ, templ_for_count, cv::COLOR_BGR2HSV);
|
||||
}
|
||||
else {
|
||||
cv::cvtColor(image, image_for_match, cv::COLOR_BGR2RGB);
|
||||
cv::cvtColor(templ, templ_for_match, cv::COLOR_BGR2RGB);
|
||||
else if (method == MatchMethod::RGBCount) {
|
||||
image_for_count = image_for_match;
|
||||
templ_for_count = templ_for_match;
|
||||
}
|
||||
|
||||
// 目前所有的匹配都是用 TM_CCOEFF_NORMED
|
||||
@@ -136,7 +140,9 @@ std::vector<Matcher::RawResult> Matcher::preproc_and_match(const cv::Mat& image,
|
||||
return mask;
|
||||
};
|
||||
|
||||
if (params.mask_range.empty()) {
|
||||
if (params.mask_range.empty() || method == MatchMethod::RGBCount || method == MatchMethod::HSVCount) {
|
||||
// workaround: 数色时的模板匹配忽略 maskRange
|
||||
// TODO: 区分 maskRange 和 colorRange
|
||||
cv::matchTemplate(image_for_match, templ_for_match, matched, match_algorithm);
|
||||
}
|
||||
else {
|
||||
@@ -150,9 +156,8 @@ std::vector<Matcher::RawResult> Matcher::preproc_and_match(const cv::Mat& image,
|
||||
}
|
||||
|
||||
if (method == MatchMethod::RGBCount || method == MatchMethod::HSVCount) {
|
||||
// 待匹配图像与模板中指定颜色的像素数量比值,越接近1越相似
|
||||
auto templ_active_opt = calc_mask(templ_for_match, false);
|
||||
auto image_active_opt = calc_mask(image_for_match, false);
|
||||
auto templ_active_opt = calc_mask(templ_for_count, false);
|
||||
auto image_active_opt = calc_mask(image_for_count, false);
|
||||
if (!image_active_opt || !templ_active_opt) [[unlikely]] {
|
||||
return {};
|
||||
}
|
||||
@@ -171,9 +176,8 @@ std::vector<Matcher::RawResult> Matcher::preproc_and_match(const cv::Mat& image,
|
||||
fp.convertTo(fp, CV_32S);
|
||||
cv::Mat count_result; // 数色结果为 f1_score
|
||||
cv::divide(2 * tp, tp + fp + tp_fn, count_result, 1, CV_32F);
|
||||
// 返回的是数色和模板匹配的几何平均
|
||||
// 返回的是数色和模板匹配的点积
|
||||
cv::multiply(matched, count_result, matched);
|
||||
cv::sqrt(matched, matched);
|
||||
}
|
||||
results.emplace_back(RawResult { .matched = matched, .templ = templ, .templ_name = templ_name });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user