圆形标定板标定的opencv c++实现

2022/1/24 17:34:22

本文主要是介绍圆形标定板标定的opencv c++实现,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

圆形标定板标定的opencv c++实现

作者:Oto_G

目录
  • 圆形标定板标定的opencv c++实现
    • 源代码
    • 实现环境
    • 文件说明
    • 实现步骤
      • 图像预处理模块
        • 读取待标定图像
        • 创建灰度图像
        • 进行均值模糊
        • OTSU自适应阈值二值化
        • 开操作和闭操作
        • 将二值图像反色,创建Calibration对象
      • 识别顶点模块
        • 查找内五边形顶点
        • 确定内四边形四点
        • 透视变换
      • 获取圆心模块
        • 获得所有理想圆心
        • 灰度重心法确定圆心
        • 反透视变换
        • 校准图像
    • 实现缺陷

源代码

源码见github:CircleCalibrationTarget

实现环境

  • 平台:win10

  • VSCode V1.63.2

  • cmake V3.18.4

  • opencv V4.5.2

  • mingw64 V8.1.0

文件说明

  • Calibrating.h

    • Calibration类、所有使用的方法的声明
  • Calibrating.cpp

    • Calbrating.h的实现
  • AutoCalibrating.cpp

    • 主程序

实现步骤

图像预处理模块

目的是获得可标定的二值图像

读取待标定图像

使用imread函数读取需要标定的图像

bigWork_1

创建灰度图像

使用cvtColor函数将彩色图像转为灰度图像COLOR_BGR2GRAY

bigWork_2

进行均值模糊

使用blur函数对图像进行均值滤波处理,目的是减弱原图像中噪声对接下来的标定产生的影响

不预先进行均值模糊可能会导致之后找不到标定板轮廓

bigWork_3

OTSU自适应阈值二值化

使用OTSU自适应阈值算法获得获取二值图像,原理就是切割原图像为多个子图,对每个子图进行OTSU

这里使用自适应OTSU算法而不是标准二值化或是全局OTSU是考虑到图像拍摄时可能存在光照等影响,会导致寻找全局性质的阈值进行二值化会效果不佳,如使标定板图像残缺等,于是综合考虑实现难度和效果,选择使用自适应阈值的OTSU算法进行图像二值化

bigWork_4

开操作和闭操作

对图像依次进行一次开操作和闭操作,将内部空点填补并连接边缘断点处

这一步并不是在整个标定过程中起到决定性作用,但增加对图像的开闭操作后能够对图片中的一些噪点和边缘残缺的现象进行抑制和修补,使后面要进行的边缘提取算法能够更加高效和准确(因为消除了小的独立噪点并连接了断点)

bigWork_6

将二值图像反色,创建Calibration对象

使用bitwise_not函数进行反色处理,并创建未透视变换的Calibration对象

这里的Calibration是自定义的一个类,为了更加方便地管理寻找到的标定板边缘和内圆点的坐标,不用多次将这些坐标写入内存,造成内存的浪费

bigWork_7

识别顶点模块

基于上一个模块得到的二值图像,在图像内寻找标定板位置

查找内五边形顶点

先通过findContours查找轮廓,然后获得当前图片能够正常标定的标定板面积下限,再由面积下限作为阈值来进行多边形拟合,确定图像内是否存在大的多边形

如果存在则查找这些多边形是否是标定板的内五边形,这里通过边长关系进行限制。若存在则对五边形的各个顶点进行排序和标记,若不存在则返回相应提示并退出程序

bigWork_8

确定内四边形四点

通过计算与五边形最短边两顶点的欧式距离之和的最小值获得四边形的四个顶点,并在图像上画出四边形的轮廓

bigWork_9

透视变换

对图像进行透视变换,将四边形变换为正四边形,置于左上角,并通过原图内四边形四点获得透视变换后正方形四点

这一步的目的是方便后一步获得理想的圆心,因为标定板的各长度比值是固定的,所以很容易求出透视变换后的理想圆心得位置

bigWork_10

获取圆心模块

获得标定板内圆形的圆心坐标

获得所有理想圆心

创建透视变换后的Calibration对象,根据透视变换后的内四边形获得所有理想中心点,并标记在图像中

理想圆心和实际的圆心还是存在较大差距的,当然理想圆心仍然有用,以理想圆心为中心圈出一个矩形框,作为每一个需要标定的圆心的感兴趣区域

bigWork_12

灰度重心法确定圆心

截取矩形区域,与二值图相与,使用灰度重心法确定实际圆心,标记在图中

这一步灰度重心法之前我们进行了改良,将一开始得到的二值图像与我们的灰度图像进行相与的操作,这样我们就只保留了图像圆中的灰度信息,消除了圆外的灰度变化对接下来的灰度重心算法造成的影响

同时这里采用灰度重心法也是因为考虑到标定板图像拍摄时可能由于光线问题和具体畸变问题导致拍摄后的图像存在阴影和形状畸变的影响,使用灰度重心法能够较好的规避上述两种情况带来的影响

bigWork_13

反透视变换

对确定的中点进行反透视变换,得到完成圆点标记后的图像

bigWork_14

校准图像

获取相机参数,结合标定板数据,校准原始图像的畸变

bigWork_15

实现缺陷

直接使用两条延长线交点确定第四个点的方法存在误差,因为图像存在畸变

使用透视变换后再进行灰度重心法标定圆心存在一定误差,因为图像存在畸变



这篇关于圆形标定板标定的opencv c++实现的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程