[OpenCV】相机标定之棋盘格角点检测与绘制

news/2025/3/22 21:51:51/

在OpenCV中,棋盘格角点检测与绘制是一个常见的任务,通常用于相机标定。
棋盘格自定义可参考: OpenCV: Create calibration pattern

摘自<a class=opencv官网" />

目录

  • 1. 棋盘格角点检测 findChessboardCorners()
  • 2. 棋盘格角点绘制 drawChessboardCorners()
  • 3. 代码示例

1. 棋盘格角点检测 findChessboardCorners()

函数原型是

//C++使用时,包含头文件
#include <opencv2/calib3d.hpp>bool cv::findChessboardCorners	(InputArray image,
Size patternSize,
OutputArray corners,
int	flags = CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORMALIZE_IMAGE)		
Python://opencv4.8.0
cv.findChessboardCorners(	image, patternSize[, corners[, flags]]	) ->	retval, corners

这里引用官方的文档内容–参数介绍
引用于<a class=opencv官方文档" />

参数成员
image 来源棋盘视图。它必须是8位灰度或彩色图像。
这里如果输入是彩色图像,最好先使用 cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 转换为灰度图像。
patternSize 棋盘格的内部角点数量,格式为 (columns, rows)。必须是棋盘格内部的角点数量,而不是棋盘格的方块数量。例如,一个 10x7 的棋盘格方块,其内部角点数量是 9x6。
注意:这里的角点是指棋盘格内部的交叉点,而不是棋盘格的方块数量。
corners 检测到的角点的输出数组。
如果找到角点,corners 将是一个包含所有角点坐标的数组,形状为 (N, 1, 2),其中 N 是角点的数量。
flags 各种操作标志,可以为零或以下值的组合:
*CALIB_CB_ADAPTIVE_THRESH 使用自适应阈值将图像转换为黑白,而不是固定的阈值水平(根据平均图像亮度计算)。
*CALIB_CB_NORMALIZE_IMAGE 在应用固定或自适应阈值之前,用均衡器归一化图像灰度系数。
*CALIB_CB_FILTER_QUADS 使用附加标准(如轮廓面积、周长、类似正方形的形状)过滤掉在轮廓检索阶段提取的错误四边形。
*CALIB_CB_FAST_CHECK 在图像上运行快速检查,寻找棋盘角,如果没有找到,则快捷调用。当没有观察到棋盘时,这可以显著地加速退化条件下的调用。
返回值
ret
布尔值,表示是否成功找到棋盘格角点。如果找到角点,返回 True;否则返回 False。
corners
检测到的角点坐标,是一个形状为 (N, 1, 2) 的 NumPy 数组,其中 N 是角点的数量。每个角点的坐标是 (x, y),表示其在图像中的像素位置。

该函数试图确定输入图像是否是棋盘图案的视图,并定位棋盘的内部角。如果找到了所有的角,并按一定的顺序(逐行,每行从左到右)放置,则该函数返回一个非零值。否则,如果函数未能找到所有的角或对它们重新排序,它将返回0。例如,一个规则的棋盘有8×8个正方形和7×7个内角,即黑色正方形相互接触的点。检测到的坐标是近似的,为了更精确地确定它们的位置,该函数调用cornerSubPix。如果返回的坐标不够精确,也可以使用带有不同参数的cornerSubPix函数。

2. 棋盘格角点绘制 drawChessboardCorners()

函数原型是

//头文件包含
#include <opencv2/calib3d.hpp>void cv::drawChessboardCorners(InputOutputArray image,
Size patternSize,
InputArray corners,
bool patternWasFound )		
Python://opencv4.8.0
cv.drawChessboardCorners(image, patternSize, corners, patternWasFound)->image

参数介绍,引用于官方文档
引用于<a class=opencv官网" />

image ; 目标图像。它必须是8位彩色图像。
patternSize 棋盘行和列的内角数量(patternSize = cv::Size(points _ per _ row,points_per_column))。必须是棋盘格内部的角点数量,而不是棋盘格的方块数量。例如,一个 10x7 的棋盘格方块,其内部角点数量是 9x6。
corners: 检测到的角的数组,findChessboardCorners的输出。
patternWasFound: 这个参数表明是否找到了完整棋盘。此处应导入使用findChessboardCorners 函数时所获取到的返回值。
这个函数用于绘制单个棋盘角,如果没有找到棋盘,则显示为红色圆圈;如果找到了棋盘,则显示为用线条连接的彩色角。

3. 代码示例

以下是一个简单的步骤和代码示例,展示如何使用OpenCV检测棋盘格的角点并绘制它们。

C++版本

#include <opencv2/opencv.hpp>
#include <iostream>int main() {// 读取图像cv::Mat image = cv::imread("chessboard.png");if (image.empty()) {std::cerr << "无法加载图像!" << std::endl;return -1;}// 转换为灰度图像cv::Mat gray;cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);// 定义棋盘格的内部角点数量cv::Size patternSize(9, 6); // 例如,9x6 的棋盘格// 存储角点的容器std::vector<cv::Point2f> corners;// 查找棋盘格角点bool found = cv::findChessboardCorners(gray, patternSize, corners);if (found) {std::cout << "找到 " << corners.size() << " 个角点" << std::endl;// 优化角点位置cv::TermCriteria criteria(cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 30, 0.001);cv::cornerSubPix(gray, corners, cv::Size(11, 11), cv::Size(-1, -1), criteria);// 绘制角点cv::drawChessboardCorners(image, patternSize, cv::Mat(corners), found);// 显示结果cv::imshow("Chessboard Corners", image);cv::waitKey(0);} else {std::cout << "未找到棋盘格角点" << std::endl;}cv::destroyAllWindows();return 0;
}

代码说明
1. 图像读取与灰度转换
使用 cv::imread 读取图像,并检查是否成功加载。
使用 cv::cvtColor 将彩色图像转换为灰度图像。
2. 定义棋盘格尺寸
使用 cv::Size 定义棋盘格的内部角点数量(例如 9x6)。
3. 查找角点
使用 cv::findChessboardCorners 查找棋盘格角点。如果找到角点,返回 true,并将角点坐标存储在 corners 中。
4. 优化角点位置
使用 cv::cornerSubPix 对角点位置进行亚像素优化,以提高精度。
5. 绘制角点
使用 cv::drawChessboardCorners 在图像上绘制检测到的角点。
6. 显示结果
使用 cv::imshow 显示带有角点的图像,并等待用户按键退出。

python_126">python版本

步骤

  1. 导入必要的库:导入OpenCV和NumPy库。
  2. 读取图像:读取包含棋盘格的图像。
  3. 查找角点:使用cv2.findChessboardCorners函数查找棋盘格的角点。
  4. 优化角点位置:使用cv2.cornerSubPix函数优化角点位置。
  5. 绘制角点:使用cv2.drawChessboardCorners函数绘制检测到的角点。
  6. 显示结果:显示带有角点的图像。

代码示例

python">import cv2
import numpy as np# 读取图像
image = cv2.imread('chessboard.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 定义棋盘格的尺寸(内部角点的数量)
pattern_size = (9, 6)  # 例如,9x6的棋盘格# 查找棋盘格角点
ret, corners = cv2.findChessboardCorners(gray, pattern_size, None)if ret:print(f"找到 {len(corners)} 个角点")# 优化角点位置criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)corners = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)# 绘制角点cv2.drawChessboardCorners(image, pattern_size, corners, ret)# 显示结果cv2.imshow('Chessboard Corners', image)cv2.waitKey(0)cv2.destroyAllWindows()
else:print("未找到棋盘格角点")

代码说明

  1. cv2.findChessboardCorners:这个函数用于查找棋盘格的角点。它需要输入灰度图像、棋盘格的尺寸(内部角点的数量),以及一些可选参数。如果找到角点,返回True和角点的坐标。
  2. cv2.cornerSubPix:这个函数用于优化角点的位置,使其更加精确。
  3. cv2.drawChessboardCorners:这个函数用于在图像上绘制检测到的角点。

注意事项

  • 棋盘格的尺寸(内部角点的数量)需要根据实际的棋盘格进行调整。
  • 如果图像中没有找到棋盘格角点,ret将为False,此时需要检查图像和棋盘格尺寸是否正确。

运行结果
运行代码后,你将看到图像上绘制了检测到的棋盘格角点。这些角点可以用于进一步的相机标定或其他计算机视觉任务。


http://www.ppmy.cn/news/1581235.html

相关文章

OceanBase 社区年度之星专访:社区“老炮”代晓磊与数据库的故事

2024年年底&#xff0c;OceanBase 社区颁发了“年度之星”奖项&#xff0c;以奖励过去一年中对社区发展做出卓越贡献的个人。今天&#xff0c;我们有幸邀请到“年度之星”得主 —— 知乎的代晓磊老师&#xff0c;并对他进行了专访。 代晓磊老师深耕数据库运维与开发领域超过14…

【问题解决】Postman 测试报错 406

现象 Tomcat 日志 org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.logException Resolved org.springframework.web.HttpMediaTypeNotAcceptableException: No acceptable representation HTTP状态 406 - 不可接收 的报错&#xff0c;核心原因 客…

AFFiNE:下一代开源全能知识库工具,重新定义协作与创作

一、AFFiNE是什么? AFFiNE(发音为 [ə‘fain])是一款集文档编辑、无限白板、数据库管理于一体的开源生产力工具,被开发者誉为“Notion + Miro + Airtable”的终极融合体。其目标是为用户提供隐私优先、高度可定制且功能强大的知识操作系统(KnowledgeOS),适用于个人创作…

bash中如何区分系统命令和自定义函数

在 Bash 中&#xff0c;系统命令和自定义函数可以通过以下几种方式来区分&#xff1a; 使用 type 命令 type 命令可以显示一个命令的类型&#xff0c;帮助区分系统命令、别名、函数、内置命令等。 # 检查系统命令 type ls # 输出&#xff1a;ls is /bin/ls# 检查自定义函数 m…

python力扣42.接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] …

Kotlin标准函数库学习

apply&#xff1a;apply 函数可看作一个配置函数&#xff1a;你可以传入一个接收者&#xff0c;然后调用一系列函数来配置它以便使用。如果提供lambda 给apply 函数执行&#xff0c;它会返回配置好的接收者。 apply 可以用在初始化时&#xff0c;的不断引用的情况。 //原始代…

在 Windows 系统下,将 FFmpeg 编译为 .so 文件

1. 准备环境 确保你的 Windows 系统已安装以下工具&#xff1a; Android Studio NDK&#xff08;Native Development Kit&#xff09; MSYS2&#xff08;用于提供类 Unix 环境&#xff09; FFmpeg 源码 Git Bash&#xff08;可选&#xff0c;推荐使用&#xff09; 安装 …

【leetcode hot 100 78】子集

解法一&#xff1a;回溯法 class Solution {public List<List<Integer>> subsets(int[] nums) {List<List<Integer>> result new ArrayList<List<Integer>>();List<Integer> temp new ArrayList<Integer>();backtrace(0, n…