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

news2025/3/12 10:30:14

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

1. 引言

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

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

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

2. 代码解析

完整代码如下:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2300624.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DeepMind发布Matryoshka(套娃)量化:利用嵌套表示实现多精度LLM的低比特深度学习

本文将介绍 Google DeepMind 提出的 Matryoshka 量化技术,该技术通过从单个大型语言模型 (LLM) 实现多精度模型部署,从而革新深度学习。我们将深入研究这项创新技术如何提高 LLM 的效率和准确性。 随着深度学习模型在规模和复杂度上持续增长&#xff0c…

Java-数据结构-(HashMap HashSet)

一、Tree和Hash的区别 在上一篇文章中,我们讲到了"TreeMap"和"TreeSet",但当我们刷题的时候却会发现,实际应用Map和Set时,却常常都只会用"HashMap"和"HashSet",这是为什么呢…

el-table 结合 slot 具名插槽遍历封装列表模板

基础效果 要实现以上效果&#xff0c;可对 el-table 进行封装&#xff0c;将列配置视为数组&#xff0c;循环 el-table-column 标签模板组件 <div class"tableSlot"><el-table :data"dataList" border><el-table-columnv-for"(item, …

游戏引擎学习第108天

仓库:https://gitee.com/mrxiao_com/2d_game_2 看一下我们现在的进展 今天的工作重点是处理游戏中的Z轴问题&#xff0c;特别是如何在不同的层级之间进行移动&#xff0c;并确保Z轴的处理方式与真实世界中的透视效果一致。当前&#xff0c;游戏中的Z轴运动存在问题&#xff0…

遵循规则:利用大语言模型进行视频异常检测的推理

文章目录 速览摘要01 引言02 相关工作视频异常检测大语言模型 03 归纳3.1 视觉感知3.2 规则生成Normal and Anomaly &#xff08;正常与异常&#xff09;Abstract and Concrete &#xff08;抽象与具体&#xff09;Human and Environment &#xff08;人类与环境&#xff09; 3…

网页制作01-html,css,javascript初认识のhtml的基本标记

一、 Html简介 英文全称是 hyper text markup language,超文本标记语言,是全球广域网上描述网页内容和外观的标准. Html作为一款标记语言,本身不能显示在浏览器中.标记语言经过浏览器的解释和编译,才能正确地反映html标记语言的内容. 1.html 的基本标记 1&#xff09;头部标…

linux常用命令大全(包括抓包、网络检测、路由等,做项目一点点总结而来!)

文章目录 常用命令**apt相关****ls**&#xff1a;**cd****cp****ls -l | grep ssh**&#xff1a;会列出当前目录中包含 “ssh” 的文件或目录的详细信息。**系统资源**linux路由相关抓包工具和命令tcpdumpwiresharktshark iperf 常用命令 通过上下方向键 ↑ ↓ 来调取过往执行过…

Linux学习笔记之虚拟地址空间

1.示例引入 运行如下代码那么运行结果如下图。 #include<stdio.h> #include<unistd.h>int main() {pid_t id fork();if(id-1){printf("创建进程错误&#xff01;\n");return 1;}int size0;if(id0){//子进程while(1){printf("我是子进程&#xff0c…

HTTP的“对话”逻辑:请求与响应如何构建数据桥梁?

一、前言 作为现代互联网通信的基石&#xff0c;HTTP协议定义了客户端与服务器之间的“对话规则”。每一次网页加载、API调用或文件传输的背后&#xff0c;都离不开精心构造的HTTP请求与响应。请求中封装了用户的意图——从请求方法、资源路径到提交的数据&#xff1b;响应则承…

[论文阅读] SeeSR: Towards Semantics-Aware Real-World Image Super-Resolution

文章目录 一、前言二、主要贡献三、Introduction四、Methodology4.1 Motivation &#xff1a;4.2Framework Overview.** 一、前言 通信作者是香港理工大学 & OPPO研究所的张磊教授&#xff0c;也是图像超分ISR的一个大牛了。 论文如下 SeeSR: Towards Semantics-Aware Rea…

LM Studio笔记

一、什么是 LM Studio&#xff1f; LM Studio 是一款功能强大、易于使用的桌面应用程序&#xff0c;用于在本地机器上实验和评估大型语言模型&#xff08;LLMs&#xff09;。它允许用户轻松地比较不同的模型&#xff0c;并支持使用 NVIDIA/AMD GPU 加速计算。 功能集&#xff1…

Linux CentOS 7部署Vulhub靶场

漏洞复现环境&#xff1a; 1、Linux操作系统中通过Docker部署的Vulhub靶场&#xff1a; docker docker-compose 2、Nmap扫描工具 一、部署靶场 1、安装Docker 1、下载docker yum install docker 安装完成&#xff0c;如下图&#xff1a; 2、开启docker服务 [rootlocalhost…

Golang GORM系列:GORM分页和排序

高效的数据检索和表示是应用程序开发的关键方面。GORM是健壮的Go对象关系映射库&#xff0c;它为开发人员提供了强大的工具来实现这一点。无论你是在构建动态web应用程序还是数据密集型服务&#xff0c;掌握GORM中的分页和排序使您能够提供无缝且高效的用户体验。本文我们将深入…

【怎么使用Redis实现一个延时队列?】

怎么使用Redis实现一个延时队列? 详细说明Java代码示例解释注意事项使用Redis实现延时队列通常通过有序集合(Sorted Set)来实现,利用Redis的ZSET类型及其相关命令可以很方便地实现这一功能。 有序集合中的每个元素都有一个分数(score),我们可以利用这个分数来存储消息需…

HarmonyNext上传用户相册图片到服务器

图片选择就不用说了&#xff0c;直接用 无须申请权限 。 上传图片&#xff0c;步骤和android对比稍微有点复杂&#xff0c;可能是为了安全性考虑&#xff0c;需要将图片先拷贝到缓存目录下面&#xff0c;然后再上传&#xff0c;当然你也可以转成Base64&#xff0c;然后和服务…

宝塔docker 安装oracle11G

1、拉取镜像 sudo docker pull iatebes/oracle_11g #iatebes为用户名2、查看镜像 sudo docker images3、创建并运行容器 docker run -d --privileged --name oralce11g -p 1521:1521 iatebes/oracle_11g4、登录到容器 5、进入容器并修改system用户密码 docker exec -it orac…

计算机视觉-OpenCV图像处理

1.Matplotlib数据可视化&#xff08;绘制图像直方图、可视化矩阵&#xff09; # Matplotlib 数据可视化&#xff08;绘制图像直方图、可视化矩阵&#xff09; # 本节主要讲解如何使用 Matplotlib 绘制图像直方图和可视化矩阵。 # 1. 绘制图像直方图 # 2. 可视化矩阵# 1. 绘制图…

【论文笔记】Transformer^2: 自适应大型语言模型

Code repo: https://github.com/SakanaAI/self-adaptive-llms 摘要 自适应大型语言模型&#xff08;LLMs&#xff09;旨在解决传统微调方法的挑战&#xff0c;这些方法通常计算密集且难以处理多样化的任务。本文介绍了Transformer&#xff08;Transformer-Squared&#xff09;…

【医学影像AI】50个眼科影像数据集(1)分类任务

【医学影像】50个眼科影像数据集&#xff08;1&#xff09;分类任务 【医学影像】50个眼科影像数据集&#xff08;2&#xff09;分割任务 【医学影像】50个眼科影像数据集&#xff08;3&#xff09;其它任务 【医学影像AI】50 个眼科影像数据集&#xff08;1&#xff09;分类任…