计算机视觉--opencv圆点提取

参考资料

https://blog.csdn.net/app_12062011/article/details/51953030
https://blog.csdn.net/gggttt222/article/details/92976511
https://blog.csdn.net/Ketal_N/article/details/88829741
https://docs.opencv.org/3.4.11/d9/d0c/group__calib3d.html#gad1205c4b803a21597c7d6035f5efd775


结论

本次博客就是一个缝合怪,把自己看到的与opencv圆点棋盘相关的资料整理一下。当然也会在其中加入一些自己的理解,不然就是真的缝合怪了。
本博客将简单介绍一下findCirclesGrid使用的一些注意事项和技巧。


findCirclesGrid

1 opencv api介绍

首先来看一下opencv api的,毕竟这是最权威的材料。

bool cv::findCirclesGrid	(	
    InputArray 	image, #输入图片,可以是单通道也可以是三通道
    Size 	patternSize, # 棋盘格的大小,分别是每行有几个圆和每列有几个圆,后边会举例子
    OutputArray 	centers, # 输出的圆心列表
    int 	flags, # 共有三个参数,CALIB_CB_SYMMETRIC_GRID 表示棋盘格是对称的,CALIB_CB_ASYMMETRIC_GRID表示棋盘格是不对称的,CALIB_CB_CLUSTERING是一个特殊参数,在仿射变换比较严重时可以使用
    const Ptr< FeatureDetector > & 	blobDetector, # 圆提取方法
    CirclesGridFinderParameters 	parameters  # 一些额外参数,但是文档里未介绍如何使用
)	

根据以上api,不难发现一共有2个主要的地方需要额外注意:

  1. 圆形格的类型和大小
  2. 圆形的提取方法

接下来将主要围绕这两个问题展开。

2 圆形格的类型和大小

首先展示两种常用的圆形格,如下图所示(来源于参考资料);其中第一种时非对称圆形格(对应CALIB_CB_ASYMMETRIC_GRID),图中也已经展示了如何读取其大小;第二种时对称圆形格(对应CALIB_CB_SYMMETRIC_GRID ),此时大小就很明显了,7*7。通常情况下,对称和非对称并没有太大的区别,但是明显发现对称圆形格旋转后可能还是一样的,此时可能会对后方交会等等操作带来一些误解,因此通常而言都推荐使用非对称;除非本身旋转角度不大,那就无所谓。

另外需要额外注意的时,findCirclesGrid最终需要输出的时grid。一般情况下,当影像的倾角比较大的时候,可能会难以寻找grid。此时可以利用CALIB_CB_CLUSTERING。
CALIB_CB_CLUSTERING 会以层次Kmean方式聚类检测值,并计算检测点围成的凸包角点,并排序外部角点。同时,会根据排序后的2D外部角点和理想估计点,计算单应性H,再计算出所有监测点的投影点,再根据Knn选取跟理想估计点近似最近点,作为实际输出的圆形中点。(来源参考文献
计算机视觉--opencv圆点提取_第1张图片
计算机视觉--opencv圆点提取_第2张图片

3 圆形的提取方法

通常,如果不加以特殊说明,findCirclesGrid提取圆形的时候使用默认const Ptr &blobDetector = SimpleBlobDetector::create(),其默认参数列表如下:

	// 参考:https://blog.csdn.net/app_12062011/article/details/51953030
    thresholdStep = 10;    //二值化的阈值步长
    minThreshold = 50;   //二值化的起始阈值
    maxThreshold = 220;    //二值化的终止阈值 
    
    //重复的最小次数,只有属于灰度图像斑点的那些二值图像斑点数量大于该值时,该灰度图像斑点才被认为是特征点  
    minRepeatability = 2;     
    //最小的斑点距离,不同二值图像的斑点间距离小于该值时,被认为是同一个位置的斑点,否则是不同位置上的斑点  
    minDistBetweenBlobs = 10;  
  
    filterByColor = true;    //斑点颜色的限制变量  
    blobColor = 0;    //表示只提取黑色斑点;如果该变量为255,表示只提取白色斑点  
  
    filterByArea = true;    //斑点面积的限制变量  
    minArea = 25;    //斑点的最小面积  
    maxArea = 5000;    //斑点的最大面积  
  
    filterByCircularity = false;    //斑点圆度的限制变量,默认是不限制  
    minCircularity = 0.8f;    //斑点的最小圆度  
    //斑点的最大圆度,所能表示的float类型的最大值  
    maxCircularity = std::numeric_limits::max();  
  
    filterByInertia = true;    //斑点惯性率的限制变量  
    //minInertiaRatio = 0.6;  
    minInertiaRatio = 0.1f;    //斑点的最小惯性率  
    maxInertiaRatio = std::numeric_limits::max();    //斑点的最大惯性率  
  
    filterByConvexity = true;    //斑点凸度的限制变量  
    //minConvexity = 0.8;  
    minConvexity = 0.95f;    //斑点的最小凸度  
    maxConvexity = std::numeric_limits::max();    //斑点的最大凸度  

单纯看以上参数,不难发现几个参数设置其实不一定总是合理。包括:手工设定阈值进行二值分割,以及手工设定阈值确定圆形的大小等等。

额外资料整理

博主gggttt222分享了一些有意思的东西,即圆形经过仿射变换时会变成椭圆,进而干扰标定精度。参考一下,我列出了一些论文,有空可以看看:

Accurate calibration method for a structured light system
《光栅投影 三维精密测量》(达飞鹏)
Geometric Correction of Circular Fiducials
Valication Code for Circular Correction
https://github.com/opencv/opencv/wiki/GSoC_2019#for-students-interested-in-applying

你可能感兴趣的:(Opencv)