OpenCV中角点未检测到原因与FindChessboardCorners函数

本文分享了一次棋盘格角点检测的实际经验,详细分析了OpenCV中FindChessboardCorners函数的使用技巧及常见问题。文章通过实验对比,强调了胶带类型、图像质量、光照条件对角点检测的影响,以及如何正确设置pattern_size参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本博客参考两位前辈的实验记录角点检测与FindChessboardCorners函数 和 OpenCV学习笔记(33)棋盘格角点检测练习程序,总结整理而成。

实验历程:

我在前几天的实验中,总是检测不到角点,很郁闷。来来回回测了七八组数据,都没有第一次测量的那种效果。因为标定板的原因,要贴掉一部分的标定板才可以使用。第一次做的实验图片有点暗,所以想把图片再重新拍一下,就随便贴了一下,这一随便拍就出现问题了,导致角点提取不出来,然后又以为是曝光问题,图片太暗了,导致图片角点提取不出来,又去调整曝光,拍了几组照片还是找不到角点,后来感觉是透明胶带的问题,改用纸胶带,用纸胶带可以去除透明胶带的一些问题,比如透明胶带放时间长了,拉出来透明胶带边缘有些黑边,也会影响后面的角点提取,用新的透明胶带,好好贴,应该也没啥问题。纸透明一点不会影响角点的提取,只要被纸覆盖住了,基本就不会被检测到角点。下面是我实验中因为胶带的原因检测不到的角点实验结果输出图:

透明胶带贴到内角点上,影响角点的提取

结合上面实验阐述——

反思实验拍照和贴纸注意事项:

  • 如果因为学校的标定板,不适用OpenCV算法,就需要贴掉一部分来使用,毕竟买一块新的精度高点的标定板代价还是很大的,能用学校已经有的,尽量利用已经有的资源。
  • pattern_size参数传递内点数,内点是黑色方块相互连通的位置。为了便于辨识方向,每行每列对应的角点数不能相同 。如果行列数相同,那么函数每次画出来的角点起始位置会变化,不利于标定。 
  • 要学会将能提取出来角点在图片上显示出来,这样有利于找到原因,而不是去盲目的去猜测原因是啥,在这要特别感谢OpenCV学习笔记(33)棋盘格角点检测练习程序这位博主的博客。
  • 在拍摄图片的时候应注意减少干扰,例如灯光、背景、自然光等。
  • 如果需要贴纸的话,可以选择纸胶带减少反光。
  • 如果不需要贴纸,在将打印的棋盘格贴在平整的板子上时,透明胶带不要贴到内角点上,不然可能影响到角点检测,如上图中我提取不到完整的角点以及下面的原图与运行结果图中的图2。
  • 提取不到角点,和贴纸的厚度没啥关系。正常的A4纸放上去,就算能看到里面的格子的影子,但它格子的边缘,你可以试试苗一下,根本苗不清楚的,所以FindChessboardCorners函数应该也会忽略它,我猜是这样的。哈哈哈。你也可以这样想,普通的透明胶带都可以影响它提取角点,那可是透明的呀,更何况纸都把角点覆盖住了,看的非常模糊了。所以贴上的纸不会因为角点行数和列数不对的原因影响角点提取。
  • 试验表明,棋盘图像不能收到干扰,换言之就是不能干扰到程序判定棋盘内角点的Size,否则检测失败。具体参见findChessboardCorners函数学习笔记

目的:

在研究坐标映射的相关问题时,遇到棋盘坐标匹配出错的问题。其中涉及到一个关键函数FindChessboardCorners。以下将对其做一定的介绍和分析。

函数介绍:

FindChessboardCorners是opencv的一个函数,可以用来寻找棋盘图的内角点位置。

 

函数形式

int cvFindChessboardCorners( const void* image, CvSize pattern_size, CvPoint2D32f* corners, int* corner_count = NULL, int flags = CV_CALIB_CB_ADAPTIVE_THRESH );

参数说明

  • Image:     输入的棋盘图,必须是8位的灰度或者彩色图像。
  • pattern_size:    棋盘图中每行和每列角点的个数。
  • Corners:     检测到的角点
  • corner_count:     输出,角点的个数。如果不是NULL,函数将检测到的角点的个数存储于此变量。
  • Flags:    各种操作标志,可以是0或者下面值的组合:
    • CV_CALIB_CB_ADAPTIVE_THRESH - 使用自适应阈值(通过平均图像亮度计算得到)将图像转换为黑白图,而不是一个固定的阈值。
    • CV_CALIB_CB_NORMALIZE_IMAGE - 在利用固定阈值或者自适应的阈值进行二值化之前,先使用cvNormalizeHist来均衡化图像亮度。
    • CV_CALIB_CB_FILTER_QUADS - 使用其他的准则(如轮廓面积,周长,方形形状)来去除在轮廓检测阶段检测到的错误方块。

补充说明

函数cvFindChessboardCorners试图确定输入图像是否是棋盘模式,并确定角点的位置。如果所有角点都被检测到且它们都被以一定顺序排布,函数返回非零值,否则在函数不能发现所有角点或者记录它们地情况下,函数返回0。例如一个正常地棋盘图右8x8个方块和7x7个内角点,内角点是黑色方块相互联通的位置。这个函数检测到地坐标只是一个大约的值,如果要精确确定它们的位置,可以使用函数cvFindCornerSubPix。
 

函数测试:

测试图像(左)和运行结果(右)

图像均为640*360的8*8黑白格棋盘图,7*7个内点。

  • 图1.计算机图像,成功检测出所有49个角点,顺序以行从左上到右下
  • 图2.正面实拍图像,检测出48个角点,其中正确47个,错误一个,没有标记顺序,只标记位置
  • 图3.正面实拍图像,成功检测出所有49个角点,顺序以行从左上到右下
  • 图4.侧面实拍图像,成功检测出所有49个角点,顺序以列从右上到左下
     

结果分析:

  • 1图与3图,角特性良好,正面拍摄,函数顺利找到角点位置
  • 2图中,未检测出的右上角两个角点可能是由于胶带干扰,角特征变的不明显。检测到的错误点是因为背景图像中有黑色物体,导致计算机误认为其为黑色方格。
  • 4图中,由于拍摄角度倾斜,棋盘图像发生变形,角点查找顺序发生变化。可以通过重新排列矩阵Corners的大小来得到1图与3图同样的效果

反思与函数应用注意事项:

  • pattern_size参数传递内点数,8*8的棋盘只有7*7内点。
  • 图像选取应注意减少干扰,例如光照与背景等。
  • Corners中的角点坐标顺序排列规律不一定是以行从左上到右下。使用坐标计算映射关系时应提高警惕,对坐标进行重新排列。

 

运行环境:win7 + VS2010 + OpenCV2.4.9

我是在我相机标定程序里面直接修改的,借鉴一些下面的代码和想法进行需要的修改。你们也可以根据需要进行相应的修改。

#include "opencv2/opencv.hpp"
 
#define m 9
#define n 6
 
using namespace std;
using namespace cv;
 
void main()
{
	Mat srcimage;
	Mat grayimage;
	vector<Point2f> corners;
	Size PatSize;
 
	PatSize.width = m;
	PatSize.height = n;
 
	srcimage = imread("a111.bmp");
	bool ret=findChessboardCorners(srcimage, PatSize, corners);
	//Mat viewGray;
	//cvtColor(srcimage, viewGray, COLOR_BGR2GRAY);
	//cornerSubPix(viewGray, corners, Size(11, 11),
	//	Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1));
	drawChessboardCorners(srcimage, PatSize, Mat(corners), ret);
	namedWindow("chessboard corners");
	imshow("chessboard corners", srcimage);
 
	waitKey(0);
}

运行结果:

 

<think>好的,我现在需要解决用户在C++中使用OpenCV检测Realsense摄像头拍摄的棋盘格失败的问题。首先,我应该回想一下常见的检测失败的原因,然后结合用户提供的引用信息,看看有没有相关的线索。 用户提到了三个引用,其中引用[2]提到了棋盘格的规格是A4纸大小,数目为8个和6个,每个格子是0.024mm的正方形。这可能和棋盘格的实际打印尺寸有关,如果用户没有按照正确的规格打印,可能导致检测失败。比如,打印的棋盘格尺寸不对,或者数目不匹配,OpenCVfindChessboardCorners函数可能无法正确识别。 接下来,用户使用Realsense摄像头,可能需要检查摄像头的校准参数是否正确。如果摄像头的内参或畸变系数没有正确设置,图像会有畸变,影响检测。此外,Realsense的RGB图像质量也很重要,比如分辨率、对焦是否准确,是否有运动模糊或者光照不足的情况。这些因素都可能导致检测失败。 然后,考虑代码实现是否正确。用户需要确认是否正确地使用了findChessboardCorners函数,传入的参数是否正确,比如棋盘格的尺寸(应该是内数,比如引用中的8x6,那么实际内可能是7x5,或者相反,需要根据实际打印的棋盘格调整)。此外,是否需要使用cornerSubPix来优化坐标,以提高检测精度。 另外,用户提供的引用[1]中提到关于OpenCV头文件的添加,如果用户在使用某些OpenCV功能时没有包含必要的头文件,比如features2d或imgproc,可能会导致函数无法正确调用。需要检查代码中是否包含了正确的头文件,比如#include <opencv2/opencv.hpp>或者特定的头文件。 还有,引用[3]提到环境问题,比如Python版本,但用户的问题是C++,可能环境问题不太相关,不过可以提醒用户确认OpenCV库是否正确链接,版本是否兼容,尤其是Realsense的SDK和OpenCV的版本是否匹配。 总结可能的原因: 1. 棋盘格打印不正确,尺寸或数不符。 2. 摄像头正确校准,导致图像畸变。 3. 光照或图像质量问题。 4. 代码中参数设置错误,如棋盘格尺寸、函数参数。 5. 缺少必要的OpenCV头文件或库链接问题。 接下来,我需要根据这些可能的原因,给出逐步的解决方案,并参考用户提供的引用,特别是引用[2]中的棋盘格规格,提醒用户检查打印是否正确。同时,引用[1]中的头文件问题也可能相关,需要包含正确的头文件。此外,建议用户使用Realsense的例程验证摄像头是否正常工作,并检查图像是否有畸变,必要时重新校准摄像头。</think>### C++ OpenCV RealSense棋盘格检测失败解决方案 #### 1. 验证棋盘格参数设置 - **正确设置棋盘格尺寸**:确保代码中棋盘格参数使用**内数量**(行列数减一)。例如引用[2]中提到的棋盘格为8x6,则代码应设置为`cv::Size(7,5)`(内数=行列数-1)[^2] ```cpp cv::Size boardSize(7,5); // 根据实际棋盘格设置 bool found = cv::findChessboardCorners(image, boardSize, corners); ``` #### 2. 检查图像预处理 - **优化图像质量**: ```cpp cv::Mat gray; cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY); cv::GaussianBlur(gray, gray, cv::Size(5,5), 1.5); // 降噪处理 ``` - **增强对比度**(可选): ```cpp cv::equalizeHist(gray, gray); // 应对光照不均 ``` #### 3. 添加亚像素优化 在基础检测后添加亚像素级优化: ```cpp if(found){ cv::TermCriteria criteria(cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 30, 0.1); cv::cornerSubPix(gray, corners, cv::Size(11,11), cv::Size(-1,-1), criteria); } ``` #### 4. 验证RealSense配置 - **检查数据流配置**: ```cpp rs2::config cfg; cfg.enable_stream(RS2_STREAM_COLOR, 640, 480, RS2_FORMAT_BGR8, 30); // 确保OpenCV兼容 ``` - **确认对齐设置**: ```cpp rs2::align align_to(RS2_STREAM_COLOR); // 对齐深度到彩色帧 ``` #### 5. 头文件包含检查 根据引用[1]的启示,确认包含必要的OpenCV头文件: ```cpp #include <opencv2/calib3d.hpp> // 棋盘格检测相关 #include <opencv2/imgproc.hpp> // 图像处理函数 #include <opencv2/highgui.hpp> // 图像显示 ``` #### 6. 调试可视化 添加可视化代码验证中间结果: ```cpp cv::drawChessboardCorners(image, boardSize, corners, found); cv::imshow("Detection Result", image); cv::waitKey(1); ``` #### 7. 硬件环境验证 - 使用`realsense-viewer`工具确认摄像头正常工作 - 检查实际打印棋盘格尺寸是否符合引用[2]标准(A4纸,0.024mm格子) - 确保棋盘格平面平整无褶皱(可粘贴在硬质平板上)
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值