You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

国际象棋棋盘图像识别异常:重复识别g8而非目标f6的问题排查

解决国际象棋绿色方块重复识别的问题

我明白你现在遇到的麻烦:明明要找第二个绿色方块f6,结果pos_loop函数老是返回已经识别过的g8位置。咱们来一步步拆解问题,找到修复方案。

首先看代码里的核心逻辑错误

你的条件判断完全写反了!两个绿色标记(g8和f6)是相同尺寸的,但你现在的代码里写的是:

if p1.height != h.height and p1.width != h.width and p1 != previous_white and p1 != previous_green:

这相当于在找尺寸完全不同的元素,和你的需求完全相反!而且直接用p1 != previous_green这种方式比较pyautogui的Box对象也不靠谱——即使坐标完全一样,不同的对象实例也会返回True,根本起不到排除已识别位置的作用。

修正后的代码思路

  1. 先修正路径:Windows路径要用双反斜杠或者原始字符串,避免转义字符报错
  2. 优先搜索绿色背景的标记(毕竟你要找的是第二个绿色方块)
  3. 通过坐标对比排除第一个已识别的位置,替代不可靠的对象比较
  4. 去掉容易导致状态混乱的全局变量,改用函数参数传递已识别位置

修正后的代码:

import pyautogui

def pos_loop(first_pos):
    # first_pos是已经正确识别的第一个绿色方块位置(g8)
    # 先收集所有绿色背景的匹配结果
    green_matches = list(pyautogui.locateAllOnScreen(r"C:\Users\Admin\Desktop\chesspic\small_on_green.png"))
    
    # 遍历结果,排除和first_pos完全重合的位置
    for match in green_matches:
        if not (match.left == first_pos.left 
                and match.top == first_pos.top 
                and match.width == first_pos.width 
                and match.height == first_pos.height):
            return match
    
    # 如果没找到绿色匹配,再按原逻辑搜索白色背景的(按需保留)
    white_matches = list(pyautogui.locateAllOnScreen(r"C:\Users\Admin\Desktop\chesspic\small_on_white.png"))
    for match in white_matches:
        if not (match.left == first_pos.left 
                and match.top == first_pos.top 
                and match.width == first_pos.width 
                and match.height == first_pos.height):
            return match
    
    return None

额外优化建议

  1. 提高识别精度:如果还是有误识别,可以加上confidence参数(需要先安装opencv-python),过滤相似度低的匹配:
green_matches = list(pyautogui.locateAllOnScreen(r"C:\Users\Admin\Desktop\chesspic\small_on_green.png", confidence=0.8))
  1. 棋盘间距校验:国际象棋棋盘格子是等距的,你可以计算两个位置的像素距离,确保它们符合棋盘格子的间距,彻底避免返回同一位置:
import math

def get_pos_distance(pos1, pos2):
    return math.hypot(pos2.left - pos1.left, pos2.top - pos1.top)

# 在返回match前加上距离判断(数值根据你的截图调整)
min_valid_distance = 50
if get_pos_distance(first_pos, match) > min_valid_distance:
    return match
  1. 彻底抛弃全局变量:全局变量很容易在多次调用函数时导致状态混乱,用函数参数传递状态会更可靠、更易维护。

原代码出错的根本原因

  • 尺寸判断写反,导致本该匹配的f6被过滤,反而错误返回了全局变量里的g8
  • 对象直接比较的方式无效,无法正确排除已识别的位置
  • 先搜索白色背景标记的逻辑,可能优先匹配到错误结果

试试上面的修正方案,应该能解决你的重复识别问题!

内容的提问来源于stack exchange,提问作者Raicha

火山引擎 最新活动