无需神经网络:如何提取Scrabble棋盘可玩区域的字母及位置?
方案选择:Scrabble棋盘字母位置提取
首先明确,方格切片法更适合你的场景,特征匹配反而会增加复杂度,原因和具体实现步骤如下:
为什么选方格切片?
Scrabble棋盘是标准的15×15网格,你提取的可玩区域图像已经是规整的棋盘部分,直接按网格切片能精准定位每个方格的位置,步骤简单可控,完全符合你不能用神经网络的要求。特征匹配更适合非规整目标的识别,这里用不上。
具体实现步骤
1. 计算单个方格的尺寸
假设提取的可玩区域图像为board_img,先获取图像宽高并计算单个方格的大小:
height, width = board_img.shape[:2] # Scrabble为15×15网格,计算每个方格的宽高 cell_width = width // 15 cell_height = height // 15
2. 遍历方格检测字母
对每个网格位置(行、列)切片出对应方格,通过简单图像分析判断是否存在字母:
import cv2 import numpy as np def detect_letters_in_board(board_img): height, width = board_img.shape[:2] cell_w = width // 15 cell_h = height // 15 letter_positions = [] # 存储有字母的位置:(行, 列, 方格x坐标, 方格y坐标, 方格宽, 方格高) for row in range(15): for col in range(15): # 计算当前方格的坐标范围 x = col * cell_w y = row * cell_h cell_img = board_img[y:y+cell_h, x:x+cell_w] # 预处理方格图像:转灰度、自适应二值化(适配不同光照) gray_cell = cv2.cvtColor(cell_img, cv2.COLOR_BGR2GRAY) binary_cell = cv2.adaptiveThreshold(gray_cell, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # 通过非零像素占比判断是否有字母(字母会占据一定面积,阈值可根据实际调整) non_zero_ratio = np.count_nonzero(binary_cell) / (cell_w * cell_h) if non_zero_ratio > 0.05: letter_positions.append((row, col, x, y, cell_w, cell_h)) # 可选:用矩形标记字母位置 cv2.rectangle(board_img, (x, y), (x+cell_w, y+cell_h), (0,255,0), 2) return letter_positions, board_img
3. 优化细节
- 如果棋盘存在轻微畸变,可先对可玩区域做透视变换矫正:通过检测棋盘四个角点,将图像映射为规整的矩形,确保网格对齐。
- 可结合轮廓检测过滤噪声:在方格内提取轮廓,过滤掉面积过小的噪声轮廓,进一步确认字母存在。
为什么不选特征匹配?
特征匹配(如SIFT、ORB)需要提前准备大量字母模板(覆盖不同字体、磨损情况),且容易受棋盘方格线、光照干扰,识别准确率和效率都不如直接切片分析,完全没必要用在这种规整网格的场景。
内容的提问来源于stack exchange,提问作者Dragos123
相关产品推荐
相关产品推荐

