利用 OpenCV 进行棋盘检测与透视变换

利用 OpenCV 进行棋盘检测与透视变换

1. 引言

在计算机视觉领域,棋盘检测与透视变换是一个常见的任务,广泛应用于 摄像机标定、文档扫描、增强现实(AR) 等场景。本篇文章将详细介绍如何使用 OpenCV 进行 棋盘检测 ,并通过 透视变换 将棋盘区域转换为一个标准的矩形图像。

我们将基于一段 Python 代码 进行分析,代码的主要任务包括:

  • 读取图像并进行预处理(灰度转换、自适应直方图均衡化、去噪)
  • 检测边缘并提取棋盘区域
  • 计算透视变换矩阵并进行变换
  • 展示和保存结果

2. 代码解析

完整代码如下:

python 复制代码
import cv2
import numpy as np

def detect_and_transform_chessboard(image_path):
    # 读取图像
    img = cv2.imread(image_path)
    if img is None:
        print("无法读取图像文件")
        return
    
    # 保存原始图像尺寸
    original_img = img.copy()
    
    # 图像预处理
    scale_percent = 50
    width = int(img.shape[1] * scale_percent / 100)
    height = int(img.shape[0] * scale_percent / 100)
    img = cv2.resize(img, (width, height))
    
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 自适应直方图均衡化
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
    gray = clahe.apply(gray)
    
    # 使用双边滤波减少噪声
    gray = cv2.bilateralFilter(gray, 11, 17, 17)
    
    found = False
    edges = cv2.Canny(gray, 50, 150)
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    if len(contours) > 0:
        contours = sorted(contours, key=cv2.contourArea, reverse=True)[:5]
        
        for contour in contours:
            epsilon = 0.02 * cv2.arcLength(contour, True)
            approx = cv2.approxPolyDP(contour, epsilon, True)
            
            if len(approx) == 4 and cv2.contourArea(approx) > 1000:
                cv2.drawContours(img, [approx], -1, (0, 0, 255), 2)
                corners_pts = approx.reshape(4, 2).astype(np.float32)
                corners_pts = order_points(corners_pts)
                found = True
                break
    
    if found and corners_pts is not None:
        target_size = (400, 400)
        target_pts = np.array([
            [0, 0],
            [target_size[0], 0],
            [target_size[0], target_size[1]],
            [0, target_size[1]]
        ], dtype=np.float32)
        
        matrix = cv2.getPerspectiveTransform(corners_pts, target_pts)
        
        warped = cv2.warpPerspective(img, matrix, target_size)
        
        cv2.namedWindow('yuantu', cv2.WINDOW_NORMAL)
        cv2.imshow('yuantu', img)
        cv2.namedWindow('zhentu', cv2.WINDOW_NORMAL)
        cv2.imshow('zhentu', warped)
        
        cv2.imwrite('detected_chessboard.png', img)
        cv2.imwrite('transformed_chessboard.png', warped)
    else:
        print("无法进行透视变换:未检测到有效的棋盘角点")
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()

def order_points(pts):
    rect = np.zeros((4, 2), dtype=np.float32)
    
    s = pts.sum(axis=1)
    rect[0] = pts[np.argmin(s)]  # 左上
    rect[2] = pts[np.argmax(s)]  # 右下
    
    diff = np.diff(pts, axis=1)
    rect[1] = pts[np.argmin(diff)]  # 右上
    rect[3] = pts[np.argmax(diff)]  # 左下
    
    return rect

if __name__ == "__main__":
    image_path = "1.jpg"
    detect_and_transform_chessboard(image_path)

原图

代码运行结果图

7. 进一步优化与拓展

7.1 多尺度图像处理

在实际应用中,棋盘大小可能存在变形和比例不一致的情况。可以使用图像金字塔(Image Pyramid)来对不同尺度的图像进行分析,提高算法的适应性。

7.2 使用深度学习改进检测

传统的边缘检测和轮廓提取方法对于复杂背景或光照变化较大的情况可能表现不佳。可以尝试使用**深度学习模型(如YOLO或OpenCV DNN模块)**来替代传统的边缘检测方法。

7.3 自动化角点提取优化

目前的角点提取方法依赖 cv2.approxPolyDP(),可以引入更精确的 Harris 角点检测Shi-Tomasi 角点检测,提高精度。

7.4 进一步增强抗噪性

可以引入 cv2.GaussianBlur()cv2.medianBlur() 进一步去除噪声,以便更清晰地检测边缘。

8. 结论

本篇文章介绍了基于 OpenCV 进行棋盘检测与透视变换的方法,详细分析了 图像预处理、边缘检测、透视变换 关键技术,并提供了优化建议。希望对你有所帮助!在实际应用中,可以结合深度学习和图像处理优化,提高检测的精度和鲁棒性。

相关推荐
加多1 分钟前
DeepSeek Harness 深度分析:用途、问题、架构原理与使用指南
人工智能·架构
风流 少年14 分钟前
Spring AI 2.0:Flux
java·人工智能·spring
小马过河R23 分钟前
Graph Engineering 深度解析:模型越强,越需要给它画好“地图”
人工智能·langchain·graph·ai工程化·harness·驾驭工程
leisoo809724 分钟前
涨停板次日表现因子怎么挖掘本地化Python全流程实战
大数据·人工智能·python
lucas_AI27 分钟前
喂张白纸也能吐出证件号?文档 MLLM 的"关系级泄露"被测出来了
人工智能·算法·掘金技术征文
Old Uncle Tom31 分钟前
手机银行用户画像设计
人工智能·智能手机
kyriewen41 分钟前
前端切图仔被 AI 新闻淹死的第 N 天,我用 TRAE Work 定时任务救了自己
前端·人工智能·trae
手写码匠41 分钟前
华为云Flexus+DeepSeek征文|Dify 多 Agent 灰度发布实战:让每一次变更都“小步快跑、随时可回滚“
人工智能·深度学习·算法·aigc
火云牌神1 小时前
分层整洁架构:标准化工程目录结构,防范 AI 越界调用
人工智能·架构·ai编程·分层架构·vibecoding
新知图书1 小时前
8.1 智能体的心跳执行模式:以定时器为核心(智能体工程)
人工智能·agent·ai agent·智能体