如何从Pluszle游戏截图识别矩阵数字并转为numpy数组?
用OpenCV轮廓识别实现Pluszle游戏数字矩阵提取
核心思路
因为游戏字体固定,所以可以通过模板匹配+轮廓定位结合的方式,先定位矩阵的每个单元格,再对每个单元格内的数字进行匹配识别,最终转成numpy数组。
具体实现步骤
1. 截图预处理
- 转为灰度图:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) - 自适应二值化(适配不同亮度的截图):
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) - 形态学去噪(消除小杂点):
kernel = np.ones((2,2), np.uint8) thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
2. 定位矩阵单元格
- 提取外部轮廓:
contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) - 筛选有效单元格轮廓:根据轮廓的面积、宽高比过滤(游戏单元格是规整的矩形,宽高比接近1,面积在固定区间内)。
- 行优先排序轮廓:先按轮廓的y坐标分组(同一行的单元格y值接近),再按x坐标排序,保证识别顺序和游戏矩阵一致。
3. 制作数字模板
- 从游戏截图中提取0-9每个数字的样本,保存为独立的小图(比如
template_0.png到template_9.png),确保模板和单元格内的数字大小、风格完全一致。 - 对所有模板执行和截图一样的灰度、二值化预处理。
4. 识别单元格数字
- 遍历排序后的轮廓,裁剪单元格区域:
x, y, w, h = cv2.boundingRect(contour) cell_img = thresh[y:y+h, x:x+w] # 可选:裁剪掉边框,比如向内缩2像素 cell_img = cell_img[2:h-2, 2:w-2] - 模板匹配识别数字:
max_score = -1 matched_digit = 0 for digit in range(10): template = cv2.imread(f"template_{digit}.png", 0) res = cv2.matchTemplate(cell_img, template, cv2.TM_CCOEFF_NORMED) score = np.max(res) if score > max_score: max_score = score matched_digit = digit # 空单元格判断:得分低于阈值(比如0.8)视为空,记为0或你的算法需要的占位符 if max_score < 0.8: matched_digit = 0
5. 转换为numpy数组
- 将识别出的数字按顺序存入列表,再转为对应行列的numpy数组:
# 假设识别出的数字列表为digits_list,rows和cols为矩阵行列数(可通过轮廓数量计算) matrix = np.array(digits_list).reshape(rows, cols)
实用优化
- 自动判断行列数:通过轮廓的y坐标分组数量得到行数,每组内的轮廓数得到列数,适配不同难度的游戏。
- 多尺度模板匹配:如果数字有轻微缩放,可对模板进行不同比例的缩放,取最高匹配得分。
内容的提问来源于stack exchange,提问作者Karapet
相关产品推荐
相关产品推荐

