如何在OpenCV数独检测程序中添加图像变换(Warping)功能?
解决数独图像透视变换问题
核心思路
要实现透视变换,关键是获取数独网格的四个顶点,并将其映射到一个正方形的目标区域。cv2.warpPerspective 需要的变换矩阵可以通过 cv2.getPerspectiveTransform 计算,而这个函数需要有序的源点和目标点。
修改后的完整代码
import cv2 import numpy as np import matplotlib.pyplot as plt def order_points(pts): # 初始化有序坐标列表:[左上, 右上, 右下, 左下] rect = np.zeros((4, 2), dtype="float32") # 左上点的x+y和最小,右下点的x+y和最大 s = pts.sum(axis=1) rect[0] = pts[np.argmin(s)] rect[2] = pts[np.argmax(s)] # 右上点的x-y差最小,左下点的x-y差最大 diff = np.diff(pts, axis=1) rect[1] = pts[np.argmin(diff)] rect[3] = pts[np.argmax(diff)] return rect def detect_and_warp_sudoku(image): # 转灰度图 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 自适应阈值处理 thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # 查找轮廓 contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 筛选面积最大的轮廓(数独网格) contour_with_max_area = max(contours, key=cv2.contourArea) # 轮廓近似为四边形 peri = cv2.arcLength(contour_with_max_area, True) approx = cv2.approxPolyDP(contour_with_max_area, 0.02 * peri, True) # 获取数独四个顶点 if len(approx) == 4: sudoku_corners = approx.reshape(4, 2).astype("float32") else: # 若无法检测到四边形,退化为 bounding rect x, y, w, h = cv2.boundingRect(contour_with_max_area) sudoku_corners = np.array([[x, y], [x+w, y], [x+w, y+h], [x, y+h]], dtype="float32") # 对顶点排序 ordered_corners = order_points(sudoku_corners) # 定义目标正方形尺寸(可根据需求调整) dst_size = 450 dst_points = np.array([[0, 0], [dst_size-1, 0], [dst_size-1, dst_size-1], [0, dst_size-1]], dtype="float32") # 计算透视变换矩阵 M = cv2.getPerspectiveTransform(ordered_corners, dst_points) # 应用透视变换 warped_image = cv2.warpPerspective(image, M, (dst_size, dst_size)) return warped_image # 加载图像并处理 image = cv2.imread('sudoku.jpg') warped_sudoku = detect_and_warp_sudoku(image) # 显示结果 plt.imshow(cv2.cvtColor(warped_sudoku, cv2.COLOR_BGR2RGB)) plt.title('Warped Sudoku') plt.show() cv2.imshow('Warped Sudoku', warped_sudoku) cv2.waitKey(0) cv2.destroyAllWindows()
关键步骤解析
轮廓近似:
使用cv2.approxPolyDP将复杂轮廓简化为四边形,0.02 * peri是近似精度(周长的2%),确保能准确捕捉数独的四个角。顶点排序:
通过计算坐标的和与差,将四个顶点按左上、右上、右下、左下的顺序排列,这是生成正确变换矩阵的前提。透视变换矩阵计算:
cv2.getPerspectiveTransform接收有序的源顶点和目标正方形顶点,生成将源区域映射到目标区域的变换矩阵。应用变换:
cv2.warpPerspective用生成的矩阵将数独网格变换为正上方视角的正方形图像,方便后续的数字识别和求解。
注意事项
- 如果图像中数独网格倾斜严重,确保轮廓检测能准确捕捉到网格边界(可调整阈值参数或增加边缘检测步骤)。
- 目标尺寸
dst_size可根据需求调整,建议设置为9的倍数(比如450=9*50),方便后续分割每个单元格。
内容的提问来源于stack exchange,提问作者Ann1207
相关产品推荐
相关产品推荐

