perf: 肉鸽节点识别 (#13427)

* perf: 节点统一 hsv

* perf: 普通战斗 hsv

* fix: 部分节点得分过低

* chore: 肉鸽节点不使用 colorWithClose

* chore: 调整安全屋模板

* perf: 优化绿色系识别
This commit is contained in:
uye
2025-07-31 19:21:20 +08:00
committed by GitHub
parent b0a53cd5b0
commit a60d6732f0
4 changed files with 128 additions and 41 deletions

View File

@@ -534,8 +534,15 @@
},
"JieGarden@Roguelike@SquadDefault": {},
"JieGarden@Roguelike@StageBoons": {
"Doc": "得偿所愿",
"templThreshold": 0.95,
"Doc": "得偿所愿 绿色系",
"method": "HSVCount",
"colorWithClose": false,
"colorScales": [
[
[70, 0, 0],
[80, 255, 170]
]
],
"next": ["JieGarden@Roguelike@StageBoonsEnter", "JieGarden@Roguelike@Stages#next"]
},
"JieGarden@Roguelike@StageBoonsEnter": {
@@ -544,9 +551,10 @@
"next": ["JieGarden@Roguelike@StageBoonsEnter", "JieGarden@Roguelike@StageEncounterJudgeClick"]
},
"JieGarden@Roguelike@StageBoskyPassage": {
"Doc": "思维边界",
"Doc": "思维边界 粉色系",
"baseTask": "JieGarden@Roguelike@Stage",
"method": "HSVCount",
"colorWithClose": false,
"colorScales": [
[
[150, 120, 50],
@@ -560,11 +568,13 @@
"next": ["JieGarden@Roguelike@StageBoskyPassageEnter", "JieGarden@Roguelike@StageEncounterJudgeClick"]
},
"JieGarden@Roguelike@StageCombatDps": {
"Doc": "普通战斗 紫色系",
"method": "HSVCount",
"colorWithClose": false,
"colorScales": [
[
[127, 80, 50],
[136, 200, 180]
[130, 0, 30],
[140, 170, 150]
]
],
"postDelay": 600,
@@ -594,9 +604,16 @@
]
},
"JieGarden@Roguelike@StageConfrontation": {
"Doc": "狭路相逢",
"Doc": "狭路相逢 青色系",
"baseTask": "JieGarden@Roguelike@Stage",
"templThreshold": 0.95,
"method": "HSVCount",
"colorWithClose": false,
"colorScales": [
[
[80, 0, 50],
[90, 255, 180]
]
],
"next": ["JieGarden@Roguelike@StageEncounterEnter", "JieGarden@Roguelike@Stages#next"]
},
"JieGarden@Roguelike@StageDreadfulFoe": {
@@ -620,12 +637,17 @@
},
"JieGarden@Roguelike@StageDreadfulFoeEnter": {},
"JieGarden@Roguelike@StageEmergencyDps": {
"templThreshold": 0.95,
"Doc": "困难战斗 红色系",
"method": "HSVCount",
"colorWithClose": false,
"colorScales": [
[
[0, 31, 51],
[179, 233, 226]
[0, 150, 50],
[10, 200, 210]
],
[
[170, 150, 50],
[180, 200, 210]
]
],
"postDelay": 600,
@@ -637,19 +659,28 @@
},
"JieGarden@Roguelike@StageEmergencyDpsEnter": {},
"JieGarden@Roguelike@StageEmergencyTransportation": {
"Doc": "先行一步拒绝可以获取2希望",
"Doc": "先行一步拒绝可以获取2希望 青色系",
"baseTask": "JieGarden@Roguelike@Stage",
"method": "HSVCount",
"colorWithClose": false,
"colorScales": [
[
[15, 1, 93],
[93, 129, 141]
[80, 0, 50],
[90, 255, 180]
]
],
"next": ["JieGarden@Roguelike@StageEncounterEnter", "JieGarden@Roguelike@Stages#next"]
},
"JieGarden@Roguelike@StageEncounter": {
"templThreshold": 0.96
"Doc": "不期而遇 青色系",
"method": "HSVCount",
"colorWithClose": false,
"colorScales": [
[
[80, 0, 50],
[90, 255, 180]
]
]
},
"JieGarden@Roguelike@StageEncounterDrawCopperResult": {
"Docs": "某些事件需要投钱来判断结果,这里要点一下投钱结果页面的对号",
@@ -697,9 +728,16 @@
"specificRect": [1100, 558, 111, 50]
},
"JieGarden@Roguelike@StageGuidance": {
"Doc": "指点迷津",
"Doc": "指点迷津 粉色系",
"baseTask": "JieGarden@Roguelike@Stage",
"templThreshold": 0.97,
"method": "HSVCount",
"colorWithClose": false,
"colorScales": [
[
[150, 120, 50],
[180, 200, 200]
]
],
"next": ["JieGarden@Roguelike@StageGuidanceEnter", "JieGarden@Roguelike@Stages#next"]
},
"JieGarden@Roguelike@StageGuidanceEnter": {
@@ -708,19 +746,28 @@
"next": ["JieGarden@Roguelike@StageGuidanceEnter", "JieGarden@Roguelike@StageEncounterJudgeClick"]
},
"JieGarden@Roguelike@StageProphecy": {
"Doc": "命运所指",
"Doc": "命运所指 青色系",
"baseTask": "JieGarden@Roguelike@Stage",
"method": "HSVCount",
"colorWithClose": false,
"colorScales": [
[
[18, 1, 94],
[93, 173, 109]
[80, 0, 50],
[90, 255, 180]
]
],
"next": ["JieGarden@Roguelike@StageEncounterEnter", "JieGarden@Roguelike@Stages#next"]
},
"JieGarden@Roguelike@StageSafeHouse": {
"templThreshold": 0.95
"Doc": "安全屋 淡青色",
"method": "HSVCount",
"colorWithClose": false,
"colorScales": [
[
[90, 60, 90],
[95, 255, 180]
]
]
},
"JieGarden@Roguelike@StageSafeHouseEnter": {
"next": ["JieGarden@Roguelike@StageSafeHouseEnter", "JieGarden@Roguelike@StageEncounterJudgeClick"]
@@ -735,7 +782,15 @@
"next": ["JieGarden@Roguelike@StageEncounterOption#next"]
},
"JieGarden@Roguelike@StageTrader": {
"templThreshold": 0.95
"Doc": "商店 绿色系",
"method": "HSVCount",
"colorWithClose": false,
"colorScales": [
[
[70, 0, 0],
[80, 255, 170]
]
]
},
"JieGarden@Roguelike@StageTraderEnter": {
"next": [
@@ -764,21 +819,14 @@
"exceededNext": ["JieGarden@Roguelike@ExitThenAbandon"]
},
"JieGarden@Roguelike@StageWindAndRain": {
"Doc": "失与得",
"Doc": "失与得 青色系",
"baseTask": "JieGarden@Roguelike@Stage",
"method": "HSVCount",
"colorWithClose": false,
"colorScales": [
[
[18, 130, 155],
[20, 180, 180]
],
[
[15, 130, 160],
[16, 150, 220]
],
[
[15, 40, 85],
[95, 120, 110]
[80, 0, 50],
[90, 255, 180]
]
],
"next": ["JieGarden@Roguelike@StageEncounterEnter", "JieGarden@Roguelike@Stages#next"]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -4,6 +4,7 @@
#include "Config/TaskData.h"
#include "Config/TemplResource.h"
#include "Utils/ImageIo.hpp"
#include "Utils/Logger.hpp"
#include "Utils/StringMisc.hpp"
@@ -38,6 +39,32 @@ Matcher::ResultOpt Matcher::analyze() const
continue;
}
#ifdef ASST_DEBUG
if (!m_params.methods.empty() && m_params.methods[0] == MatchMethod::HSVCount) {
const cv::Rect expanded_roi(
std::max(rect.x - 200, 0),
std::max(rect.y - 50, 0),
std::min(rect.width + 400, m_image.cols - std::max(rect.x - 200, 0)),
std::min(rect.height + 100, m_image.rows - std::max(rect.y - 50, 0)));
cv::Mat cropped = m_image(expanded_roi);
const cv::Rect roi_in_cropped(rect.x - expanded_roi.x, rect.y - expanded_roi.y, rect.width, rect.height);
cv::rectangle(cropped, roi_in_cropped, cv::Scalar(0, 0, 255), 2);
const std::string name = std::filesystem::path(templ_name).stem().string();
const std::string text = name + " " + std::to_string(max_val);
const cv::Size text_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, nullptr);
const cv::Point text_pos(
std::max(roi_in_cropped.x + roi_in_cropped.width / 2 - text_size.width / 2, 0),
std::max(roi_in_cropped.y - 5, text_size.height));
cv::putText(cropped, text, text_pos, cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 255), 1);
const static std::vector<int> jpeg_params = { cv::IMWRITE_JPEG_QUALITY, 95, cv::IMWRITE_JPEG_OPTIMIZE, 1 };
asst::imwrite(
utils::path("debug/hsv/" + text + "_" + utils::get_time_filestem() + ".jpg"),
cropped,
jpeg_params);
}
#endif
// FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉
m_result.rect = rect;
m_result.score = max_val;

View File

@@ -16,24 +16,36 @@ if __name__ == '__main__':
rgb_base_mask_range_ignore_dark = [[[20, 20, 20], [255, 255, 255]]] # 忽略暗色背景
# 自动判断图片的合适 mask_ranges
# image = cv2.imread(str(maa_dir / "resource" / "template" / "StartToVisit.png"))
# image = cv2.imread(str(maa_dir / "resource" / "template" / "Roguelike" / "JieGarden" / "JieGarden@Roguelike@StageConfrontation.png"))
# generate_mask_ranges(image, 'luv', luv_base_mask_range_ignore_light_dark)
# generate_mask_ranges(image, 'hsv', hsv_base_mask_range_ignore_dark)
# generate_mask_ranges(image, 'rgb', rgb_base_mask_range_ignore_dark)
# 在给定的 mask_ranges 下展示一张图
image = cv2.imread(str(maa_dir / "resource" / "template" / "StartToVisit.png"))
mask_ranges = [[[250, 250, 250], [255, 255, 255]]]
show_image_mask(image, calc_mask_from_ranges(image, mask_ranges, 'rgb', True), 'rgb')
image = cv2.imread(str(maa_dir / "resource" / "template" / "Roguelike" / "JieGarden" / "JieGarden@Roguelike@StageBoons.png"))
mask_ranges = [
[
[70, 0, 0],
[80, 255, 170]
]
]
show_image_mask(image, calc_mask_from_ranges(image, mask_ranges, 'hsv', False), 'hsv')
# mask_ranges = [[[93, 81, 130], [102, 97, 142]], [[128, 100, 164], [134, 110, 169]], [[95, 85, 145], [105, 95, 155]]]
# show_image_mask(image, calc_mask_from_ranges(image, mask_ranges, 'luv', True), 'luv')
# 在给定的 mask_ranges 下比较两张图
image1 = cv2.imread(str(maa_dir / "resource" / "template" / "StartToVisit.png"))
image2 = cv2.imread(str(maa_dir / "resource" / "template" / "StartToVisitDetermine.png"))
mask_ranges = [[[250, 250, 250], [255, 255, 255]]]
compare_2_image_with_mask_ranges(image1, image2, mask_ranges, "rgb")
compare_2_image_with_mask_ranges(image1, image2, mask_ranges, "rgb", True)
image1 = cv2.imread(str(maa_dir / "resource" / "template" / "Roguelike" / "JieGarden" / "JieGarden@Roguelike@StageSafeHouse.png"))
image2 = cv2.imread(str(maa_dir / "resource" / "template" / "Roguelike" / "JieGarden" / "JieGarden@Roguelike@StageConfrontation.png"))
mask_ranges = [
[
[85, 0, 60],
[95, 240, 240]
]
]
# compare_2_image_with_mask_ranges(image1, image2, mask_ranges, "hsv")
# compare_2_image_with_mask_ranges(image1, image2, mask_ranges, "hsv", True)
# mask_ranges = [[[93, 81, 125], [102, 97, 150]], [[95, 85, 145], [105, 95, 155]]]
# compare_2_image_with_mask_ranges(image1, image2, mask_ranges, "luv")
# compare_2_image_with_mask_ranges(image1, image2, mask_ranges, "luv", True)