角点检测与FindChessboardCorners函数
2016-07-01 13:17
363 查看
目的:
在研究坐标映射的相关问题时,遇到棋盘坐标匹配出错的问题。其中涉及到一个关键函数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中的角点坐标顺序排列规律不一定是以行从左上到右下。使用坐标计算映射关系时应提高警惕,对坐标进行重新排列。
基于VC++6.0的代码:
在研究坐标映射的相关问题时,遇到棋盘坐标匹配出错的问题。其中涉及到一个关键函数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中的角点坐标顺序排列规律不一定是以行从左上到右下。使用坐标计算映射关系时应提高警惕,对坐标进行重新排列。
基于VC++6.0的代码:
#include <iostream> #include <cv.h> #include <cxcore.h> #include <highgui.h> using namespace std; int main( ) { cout<<"Draw Chess OpenCV!"<<endl; char* filename="..//image5.jpg"; char* filename2="..//5.jpg"; IplImage* imgRGB = cvLoadImage(filename); IplImage* imgGrey = cvLoadImage(filename,CV_LOAD_IMAGE_GRAYSCALE); if (imgGrey==NULL){//image validation cout<< "No valid image input."<<endl; char c=getchar(); return 1; } //-------find chessboard corners-------------- int corner_row=7;//interior number of row corners.(this can be countered by fingers.) int corner_col=7;//interior number of column corners. int corner_n=corner_row*corner_col; CvSize pattern_size=cvSize(corner_row,corner_col); // CvPoint2D32f* corners=new CvPoint2D32f[corner_n]; CvPoint2D32f corners[49]; int corner_count; int found=cvFindChessboardCorners(//returning non-zero means sucess. imgGrey,// 8-bit single channel greyscale image. pattern_size,//how many INTERIOR corners in each row and column of the chessboard. corners,//an array where the corner locations can be recorded. &corner_count,// optional, if non-NULL, its a point to an integer where the nuber of corners found can be recorded. // CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS// check page 382-383. 0 ); cout<<"corner_count = "<<corner_count; //-------Draw the corner pattern------- cvDrawChessboardCorners( imgRGB, pattern_size, corners, corner_count, found ); cvSaveImage(filename2,imgRGB); //to summary a bit of findings. cout<<"found="<<found<<endl; cout<<"x="<<corners[1].x; cout<<",y="<<corners[1].y<<endl; cvNamedWindow("Find and Draw ChessBoard", 0 ); cvShowImage( "Find and Draw ChessBoard", imgRGB ); cvWaitKey(0); cvReleaseImage(&imgGrey); cvReleaseImage(&imgRGB); cvDestroyWindow("Find and Draw ChessBoard"); return 0; }
相关文章推荐
- 计算机视觉领域的牛人博客和有实力的研究机构
- 科研工作的关注点
- 最小外接矩形(MBR)
- 色彩量化评价指标 Quantitative measure methods for color quantization
- 图像处理的网址(转载)
- OpenCV学习笔记 第一篇 显示图像
- 图铭Android平台银行卡号识别系统
- 学习OpenCV第一课——认识、安装配置OpenCV(CodeBlocks)
- Kalman滤波
- 图像处理特征不变算子系列之KLT算子--GoodFeaturesToTrack(七)
- 《计算机视觉中的数学方法》笔记1 向量叉积的反对称矩阵表示
- Selective Search for Object Recognition
- 摄像测量相关
- Learning OpenCV Chapter3 初探OpenCV上
- 开通博客--for interest
- 计算机视觉投稿
- 摄像机几何概念
- R. Wang-Manifold-Manifold Distance with Application to Face Recognition based on Image Set读后记
- 关于Hrris角点检测的一点理解
- 计算机视觉、机器学习相关领域论文和源代码大集合--持续更新