You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pillow或imageio识别棋子并将国际象棋棋盘转为8x8布局列表

基于Pillow的无OpenCV棋子识别实现方案

核心前置逻辑

你已经完成完整棋盘区域的提取,整个棋盘是规则的正方形8x8网格,不需要做角点检测、滑动窗口这类复杂操作,仅需通过均匀切分+逐格像素相似度比对完成识别,全程不依赖OpenCV的模板匹配函数,仅用Pillow完成图像处理,imageio替代cv2做图像读取。

步骤1:棋盘格均匀切分

因为棋盘区域是已经裁剪好的完整正方形,直接按8等分拆分所有格子即可,不需要额外检测边界:

  • 图像读取阶段直接用imageio替代原有的cv2.imread,读入的图像默认是RGB格式,可直接转成Pillow的Image对象,省去通道转换步骤
  • 计算单个棋盘格的边长:square_size = 棋盘图宽度 // 8
  • 逐行列裁剪每个独立格子,按行列索引存入对应位置,为后续匹配做准备

切分参考代码:

from PIL import Image
import imageio.v2 as iio
import numpy as np

# 替代原有cv2.imread读取图像
full_img = iio.imread('checkmate_public/public/set/1/1.png')
# 如果你已经用OpenCV裁剪了棋盘区域,可直接把裁剪后的BGR数组转成RGB格式再传入Image.fromarray
board_img = Image.fromarray(full_img)

square_size = board_img.width // 8
# 初始化8x8棋盘结果列表
chess_board = [["" for _ in range(8)] for _ in range(8)]
# 存储所有切分好的格子图像
square_store = []
for row_idx in range(8):
    current_row = []
    for col_idx in range(8):
        # 定义裁剪坐标:(左,上,右,下)
        crop_box = (
            col_idx * square_size,
            row_idx * square_size,
            (col_idx + 1) * square_size,
            (row_idx + 1) * square_size
        )
        sq_img = board_img.crop(crop_box)
        current_row.append(sq_img)
    square_store.append(current_row)

步骤2:实现轻量模板匹配

Pillow和imageio本身没有内置的模板匹配接口,由于当前场景下格子尺寸和素材尺寸完全对齐,不需要做滑动窗口搜索,仅需逐格计算图像和素材的相似度即可,计算量极低:

  • 提前加载所有单独棋子、空棋盘格素材,统一缩放到和棋盘格一致的尺寸,为每个素材打对应的类型标签(比如白兵、黑车、深格空格、浅格空格)
  • 定义相似度计算函数,用均方误差衡量两个图像的像素匹配度,误差最小的素材即为当前格子的匹配结果

匹配参考代码:

def calculate_similarity(img1: Image.Image, img2: Image.Image) -> float:
    # 统一转灰度图计算,降低颜色偏差带来的匹配误差
    gray1 = np.array(img1.convert("L"))
    gray2 = np.array(img2.convert("L").resize(img1.size))
    # 计算逐像素差的平方均值,数值越小代表两个图像越相似
    return np.mean((gray1 - gray2) ** 2)

# 加载所有模板素材,统一缩放到格子大小
template_library = {}
# 示例:按实际素材路径加载
template_library["empty_dark"] = Image.open("templates/dark_blank.png").resize((square_size, square_size))
template_library["empty_light"] = Image.open("templates/light_blank.png").resize((square_size, square_size))
template_library["w_pawn"] = Image.open("templates/white_pawn.png").resize((square_size, square_size))
template_library["b_king"] = Image.open("templates/black_king.png").resize((square_size, square_size))
# 把所有需要识别的棋子素材全部加入字典即可

# 逐格子匹配填充结果列表
for row in range(8):
    for col in range(8):
        current_square = square_store[row][col]
        min_diff = float("inf")
        match_result = ""
        # 遍历所有模板找最相似的
        for label, template_img in template_library.items():
            diff = calculate_similarity(current_square, template_img)
            if diff < min_diff:
                min_diff = diff
                match_result = label
        chess_board[row][col] = match_result

匹配优化技巧

  • 如果你的棋子素材是带透明通道的PNG,计算相似度时可以仅统计棋子覆盖的非透明像素,忽略背景部分,大幅降低棋盘底色带来的匹配干扰
  • 可设置相似度阈值:当最小的像素差值超过预设阈值时,标记当前格子为识别异常,避免错配
  • 统一把素材和切分出的格子做亮度归一化,降低拍摄/截图时的全局亮度偏差对匹配结果的影响

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 22:06:04