opencv学习笔记(二十六)——相机标定之棋盘提取角点

本例程是相机标定的第一步,通过findChessboardCorners找到棋盘上的所有角点,然后再通过调用cornerSubPix亚像素精确化,找到精确的角点坐标,然后调用circle画出角点位置。

主要函数介绍:

findChessboardCorners()

  • 功能:寻找棋盘图的内角点位置
  • 函数形式: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 - 使用其他的准则(如轮廓面积,周长,方形形状)来去除在轮廓检测阶段检测到的错误方块
  • 返回值:如果找到角点返回1,没有找到返回0;

cornerSubPix

  • 功能:在角点检测中精确化角点位置
  • 函数原型:void cornerSubPix(InputArray image, InputOutputArray corners, Size winSize, Size zeroZone, TermCriteria criteria);
    C: void cvFindCornerSubPix(const CvArr* image, CvPoint2D32f* corners, int count, CvSize win, CvSize zero_zone, CvTermCriteria criteria);
  • 参数:
    • image:输入图像
    • corners:输入角点的初始坐标以及精准化后的坐标用于输出
    • winSize:搜索窗口边长的一半,例如如果winSize=Size(5,5),则一个大小为:这里写图片描述的搜索窗口将被使用。
    • zeroZone:搜索区域中间的dead region边长的一半,有时用于避免自相关矩阵的奇异性。如果值设为(-1,-1)则表示没有这个区域。
    • criteria:角点精准化迭代过程的终止条件。也就是当迭代次数超过criteria.maxCount,或者角点位置变化小于criteria.epsilon时,停止迭代过程。
  • CvTermCriteria 类:迭代算法的终止准则

    • 原型:
      • `typedef struct CvTermCriteria
        {
        int type; /* CV_TERMCRIT_ITER 和CV_TERMCRIT_EPS二值之一,或者二者的组合 */
        int max_iter; /* 最大迭代次数 */
        double epsilon; /* 结果的精确性 */
    • 宏定义:
      • CV_TERMCRIT_ITER:代终止条件为达到最大迭代次数终止
      • CV_TERMCRIT_EPS:迭代到阈值终止

    源代码

#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )   //掩藏控制台
#include

int main()
{
    cv::Mat image, Extractcorner;
    cv::vector corners;    //用来储存所有角点坐标
    cv::Size board_size = cv::Size(6, 8);   //标定板每行,每列角点数
    image = cv::imread("2.jpg");
    Extractcorner = image.clone();

    cv::Mat imageGray;
    cv::cvtColor(image, imageGray, CV_RGB2GRAY);
    bool patternfound = cv::findChessboardCorners(image, board_size, corners, cv::CALIB_CB_FAST_CHECK + cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_NORMALIZE_IMAGE);
    if (!patternfound)
    {
        std::cout << "can not find chessboard corners!" << std::endl;
        exit(1);
    }
    else
    {
        //亚像素精确化
        cv::cornerSubPix(imageGray, corners, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
    }

    //角点检测图像显示
    for (int i = 0; i < corners.size(); i++)
    {
        cv::circle(Extractcorner, corners[i], 5, cv::Scalar(255, 0, 255), 2);
    }
    cv::imshow("Extractcorner", Extractcorner);

    cv::waitKey(0);

    return 0;
}

效果:
opencv学习笔记(二十六)——相机标定之棋盘提取角点_第1张图片

你可能感兴趣的:(opencv)