文章
蓝线识别抗环境蓝干扰说明
蓝线识别抗环境蓝干扰说明 功能用途 用于解决洞穴、水面、晶体等大面积蓝色场景导致蓝线识别误判的问题。 典型表现是控制台持续输出 ,但 很高,例如 、 。这说明不是没有蓝色像素,而是环境蓝被 HSV 阈值一起算入,触发了“...
蓝线识别抗环境蓝干扰说明
功能用途
用于解决洞穴、水面、晶体等大面积蓝色场景导致蓝线识别误判的问题。
典型表现是控制台持续输出 未命中,但 pixels 很高,例如 46965、47289。这说明不是没有蓝色像素,而是环境蓝被 HSV 阈值一起算入,触发了“大面积蓝色干扰”保护,移动控制器释放 WSAD 后角色停住。
入口文件
workspace/晶核/jh_tool/core/blue_line.py- 调用入口:
BlueLineDetector.detect(frame) - 移动链路:
BlueLineProbeRunner.run(...)
关键流程
- 先按 ROI 裁剪游戏画面中部导航区域,只识别连续导航蓝线,不把桥面箭头提示当作蓝线。
- 使用 HSV 阈值保留蓝色候选区域。
- 再叠加 BGR 亮蓝导航线特征:
- 蓝通道必须足够亮。
- 绿通道必须足够亮。
- 红通道不能过高。
- 蓝通道相对红通道必须有明显优势。
- 额外叠加低饱和白蓝路线通道;按
V后的导航线有时是高亮白蓝色,红通道会高于普通蓝线阈值,不能只按“红低、蓝红差大”判断。 - 用过滤后的颜色候选 mask 统计
pixels。mask.png是颜色候选层,可能包含台阶/地砖蓝白高光;filtered.png/route_only.png才是最终保留的可循迹路线。 - 如果
pixels超过完整 ROI 的全局上限,说明环境亮蓝干扰很强;此时不会立刻判死,而是启用更严格的高亮导航线核心阈值做二次提取。 - 二次提取后如果像素量恢复到合理范围,会做蓝线形态过滤,排除怪物光点、桥面箭头、底部实心蓝块等非导航目标。
- 形态过滤只保留单根连续长度达到
100px以上、长宽比明显且不是实心块的线段;斜向进入 ROI 的蓝线会按对角跨度补充判断,避免只看宽/高导致真实斜线未命中。低于100px的蓝色碎段、两段短线拼起来的形状,都判定为未命中。 - 如果真实蓝线和台阶/地砖横向蓝白高光、角色名横条粘成一个大连通域,会进入 Hough 长线兜底,只保留足够长且接近竖向的路线线段,避免
mask.png里的横向高光影响最终循迹。 - 如果形态过滤和长线兜底后没有可用目标,或像素仍然过少/整块过大,才判定为未命中。
- 命中后同时计算
offset_x、offset_y和front;移动控制始终按住W前进,不再因为front在有/无之间抖动而切换到S。 - 横向偏移连续 2 帧超过
60px时才叠加A/D做左右修正,避免近端目标点轻微抖动导致 A/D 来回切换。 - 启动和连续丢线补投
V后,默认等待0.35s让游戏生成/刷新导航蓝线,再继续截图识别,避免把蓝线尚未出现的帧记成未命中。 - 移动过程中默认每 5 秒由后台线程短按一次
V,即使当前帧被判命中也会定时重新规划。 - 若单帧没有命中,但还没达到连续丢线阈值,移动控制沿用上一帧方向,避免木板遮挡、蓝线断裂或识别抖动导致角色停顿。
- 若连续多帧没有命中,则移动控制释放 WSAD,并由主线流程立刻按一次
V等待重新规划;如果持续未命中,会按丢线重试间隔再次补投V,避免一次重规划失败后长期空等。
配置项
配置位于 BlueLineConfig:
hsv_lower/hsv_upper:基础蓝色 HSV 范围。roi_left_ratio/roi_top_ratio/roi_width_ratio/roi_height_ratio:导航识别 ROI,目前保持中部区域,桥面箭头提示不作为蓝线目标。min_route_extent_px/min_route_aspect_ratio:蓝线形态过滤阈值;当前min_route_extent_px=100、min_route_aspect_ratio=1.45,会同时参考连通块宽高跨度和对角跨度,只保留单根连续长度达到100px以上且不是块状噪声的线段。route_line_min_vertical_ratio/route_line_hough_max_gap_px:连通域过滤失败后的长线兜底阈值;当前route_line_min_vertical_ratio=1.0,允许约 45 度及更接近纵向的真实路线通过,同时继续排除横向台阶高光。max_solid_block_fill_ratio/solid_block_max_aspect_ratio:实心蓝块过滤阈值;用于避免 ROI 底部环境蓝块或技能光抢走真实蓝线的近端质心。max_lost_frames:移动链路的连续丢线防抖阈值,默认 3 帧;短暂未命中不会立刻释放 WSAD 或按V。replan_interval:持续丢线时重复补投V的间隔,默认 1 秒;只在连续丢线状态生效。periodic_replan_interval:移动中定时补投V的间隔,默认 5 秒;设为None可关闭定时补投。replan_settle_seconds:启动或连续丢线补投V后等待蓝线刷新的时间,默认0.35s。deadzone_px/lateral_confirm_frames:横向方向死区与连续确认帧数;当前为60px和 2 帧,只有蓝线目标连续明显偏左/偏右时才叠加A/D,普通抖动只保持W。min_line_blue:导航线最低蓝通道亮度。min_line_green:导航线最低绿通道亮度。max_line_red:导航线最高红通道亮度。min_blue_red_delta:蓝通道相对红通道的最低差值。pale_hsv_lower/pale_hsv_upper:低饱和白蓝路线的 HSV 范围,用于覆盖按V后出现的高亮白线。pale_min_line_blue/pale_min_line_green/pale_min_line_red/pale_min_blue_red_delta:白蓝路线的 BGR 亮度与最低蓝红差约束。max_blue_ratio:过滤后的亮蓝线仍然过大时,判定为整块蓝色干扰。high_noise_min_line_blue/high_noise_min_line_green/high_noise_max_line_red/high_noise_min_blue_red_delta:高蓝像素场景下的二次核心阈值,只在pixels超过max_blue_ratio后启用,用于从亮蓝洞穴背景中分离真正导航线。
验证方式
使用项目虚拟环境执行:
$env:PYTHONIOENCODING='utf-8'
$env:QT_QPA_PLATFORM='offscreen'
.\.venv\Scripts\python.exe -m unittest discover -s 'workspace\晶核\tests'已新增回归测试:
test_detects_bright_route_line_inside_blue_cave_backgroundtest_detects_route_line_when_bright_cave_noise_exceeds_global_blue_limittest_rejects_fragmented_route_when_no_single_segment_reaches_100test_detects_continuous_thin_route_line_longer_than_100test_detects_diagonal_thin_route_when_bbox_axis_is_shorter_than_100test_detects_diagonal_route_when_aspect_is_slightly_below_old_thresholdtest_extracts_route_line_when_stair_highlights_touch_ittest_detects_pale_white_blue_route_line_after_vtest_detects_pale_diagonal_route_line_with_near_45_degree_slopetest_rejects_two_segment_thin_route_line_shorter_than_100_eachtest_prefers_route_line_over_bottom_blue_noisetest_detects_route_line_near_bottom_of_roitest_ignores_bridge_marker_arrows_when_route_line_is_absenttest_ignores_low_monster_glow_when_route_marker_is_absenttest_probe_runner_presses_v_periodically_while_movingtest_probe_runner_waits_after_start_v_before_first_snapshottest_probe_runner_keeps_moving_through_single_lost_frametest_probe_runner_replans_after_consecutive_lost_framestest_probe_runner_retries_v_during_long_lost_streaktest_probe_runner_keeps_w_when_route_is_below_charactertest_wsad_prioritizes_w_when_forward_route_exists_below_charactertest_wsad_keeps_w_when_route_is_below_without_forward_routetest_wsad_ignores_small_horizontal_jittertest_wsad_requires_repeated_same_side_before_lateral_key
这些测试构造“大面积洞穴蓝背景 + 亮蓝弧形导航线”、“单根连续 100px 以上细蓝线”、“宽高单轴不足 100 但对角跨度超过 100 的斜向细蓝线”、“按 V 后低饱和白蓝线”、“两段短细蓝线”、“底部实心蓝块 + 真实蓝线”、“ROI 底部 100px 以上真实蓝线”、“只有桥面箭头提示”和“只有低位怪物光效”,要求检测器必须命中真正导航线,并且不能因为背景蓝像素过多、桥面箭头、两段短线、底部实心蓝块或怪物光效接近蓝线颜色而误判。其中高亮噪声用例覆盖真实日志里 pixels 约 4.5 万到 5 万时提前停死的问题,连续长线用例覆盖低像素但确实是一整根蓝线时应命中的问题,斜向细蓝线用例覆盖 pixels 约 260 到 300 且 ROI 内有连续蓝线却被旧长度阈值误判未命中的问题,白蓝线用例覆盖真实按 V 后红通道偏高、蓝红差偏低导致旧阈值漏掉路线主体的问题,两段短线用例覆盖两段蓝色合起来像路线但不能当成连续蓝线的问题,底部蓝块用例覆盖日志里 target 被错误拉到屏幕底部的问题,移动防抖用例覆盖命中中夹杂单帧未命中时不应立即释放 WSAD/按 V 的问题,持续丢线用例覆盖一次 V 后蓝线仍不回来时必须继续补投 V 的问题,移动控制用例覆盖命中后始终保持 W、低于 60px 的横向抖动不叠加 A/D 的问题。
已知限制
- 如果游戏特效产生同样高亮、同样颜色结构的蓝色线状物,仍可能被当作导航线。
- 当前已做合成图像、单元测试、真实窗口按 V 采样和 10 帧 WSAD 短实测;真实场景仍需结合控制台日志继续观察不同地图/光效。