[Halcon&标定] 相机自标定

一、自标定含义和意义

摄像机自标定方法不需要标定块,只是通过摄像机在运动过程中建立多幅图像之间对应的关系,直接进行标定,它克服了传统标定方法的缺点,灵活性较强,它的缺点是标定过程复杂,使用非线性方法标定,鲁棒性差,精度也不高。现在已有的自标定技术大致可以分为:基于 Kruppa 方程的自标定方法、基于二次曲面的自标定方法、分层逐步标定法等。

在项目中,偶尔会遇到由于产品形状、拍摄位置等原因导致标定板很难放置的情况,此时可以考虑使用halcon自标定算法来标定相机。

halcon提供了一种自标定的算子,它可以在不用标定板的情况下,只需要一张图片,根据提取到是物体边缘的直线,来得到相机的内参,标定出相机内参(无焦距),从而完成畸变校正,因为畸变一般在图像的边缘更严重,所以需要保证在图像的四周边缘有足够的直线线段。在实际项目中拍摄物体不可能都像例程中一样有理想的直线边缘,替代方法是:用菲林片制作一张网格黑色印制(10*10,可以根据自己实际情况调整)充满整个视野。

求出了相机内参就可以进行畸变校正,因而自标定相对于采集多张标定板图像进行标定而言,在畸变校正方面更快捷,极大地方便在设备现场进行调试,但是相对于标定板标定而言,无法求出相机的外参。

后续若需要将像素单位换算至公有制单位,也可使用棋盘格、标准物、菲林片等进行转换,便可应用于测量项目;也可以利用一定网格构建XY坐标系,用于定位项目,这样在不借助标定板的情况下就可以畸变校正和测量类的项目。


二、自标定流程

1.求出拍摄物体的边缘XLD

2.使用radial_distortion_self_calibration函数,根据边缘求出相机内参

3.change_radial_distortion_cam_par 求出理想无畸变内参

4.change_radial_distortion_image 根据相机内参,对图像进行畸变校正

代码:

* 使用edges_sub_pix 或line_gauss提取图像边缘轮廓
edges_sub_pix (Image, Edges, 'canny', 1, 10, 40)
* 分割直线和圆弧
segment_contours_xld (Edges, SplitEdges, 'lines_circles', 5, 4, 2)
* 选择对校准有用的足够长的边
select_shape_xld (SplitEdges, SelectedEdges, 'contlength', 'and', 30, 100000)    
* 根据一组XLD轮廓估计镜头的畸变参数和畸变中心,以此达到校准径向畸变的目的
radial_distortion_self_calibration (SelectedEdges, CalibrationEdges, Width, Height,  0.08, 42, 'division', 'variable', 0, CamParSingleImage)
* 根据radial_distortion_self_calibration的结果,您可以通过将包含畸变参数的参数CameraParam传递给操作符change_radial_distortion_cam_par和change_radial_distortion_image来对图像进行校正,即去除径向畸变
get_domain (Image, Domain)
change_radial_distortion_cam_par ('fixed', CamParSingleImage, 0, CamParSingleImageRect)
change_radial_distortion_image (Image, Domain, ImageRectified, CamParSingleImage, CamParSingleImageRect)

write_cam_par (CamParSingleImage, 'C:/Users/Administrator/Desktop/CamParSingleImage.dat')
write_cam_par (CamParSingleImageRect, 'C:/Users/Administrator/Desktop/CamParSingleImageRect.dat')

read_cam_par ('C:/Users/Administrator/Desktop/CamParSingleImage.dat', CamParSingleImage)
read_cam_par ('C:/Users/Administrator/Desktop/CamParSingleImageRect.dat', CamParSingleImageRect)

三、核心函数

核心算子一radial_distortion_self_calibration( Contours : SelectedContours : Width, Height, InlierThreshold, RandSeed, DistortionModel, DistortionCenter, PrincipalPointVar : CameraParam ) —— 根据一组XLD轮廓估计镜头的畸变参数和畸变中心,以此达到校准径向畸变的目的

对畸变的评估是基于图像中可见大量直线的假设。由于透镜畸变,这些线将被投影成曲线轮廓。操作者现在可以确定适当的参数,通过这些参数,曲线轮廓可以被再次拉直,从而补偿透镜的畸变。

要获得合适的输入轮廓,可以使用edges_sub_pix或lines_gauss。轮廓应该是均匀分布的,并且应该位于图像边界附近,因为那里的失真程度是最大的,因此校准是最稳定的。为了提高速度和健壮性,您可以尝试获得长线性或圆形段,例如使用segment_contours_xld、union_collinear_contours_xld、union_cocircular_contours_xld或select_shape_xld。如果一个单独的图像在场景中没有包含足够的直线轮廓,你可以使用多个图像的轮廓。

操作员使用鲁棒RANSAC方法自动从场景中直线图像的轮廓中估计出这些轮廓。不满足这个条件,因此不适合校准过程的轮廓称为离群值。操作符可以处理最大的异常值百分比为50%。经过畸变校正后,如果轮廓与相关直线的平均偏差大于给定的阈值T,则将轮廓归为离群值。
在这里插入图片描述
InlierThreshold值描述包含100个点的轮廓从其关联线的平均偏差,以像素为单位。实际阈值T由InlierThreshold根据参考长度(100)和轮廓点个数m进行缩放得到,因此相似的轮廓分类相似。典型的InlierThreshold值在0.05到0.5之间。值越高,越能容忍偏差。

通过参数RandSeed,你可以控制随机行为的RANSAC算法,并迫使它返回可重复的结果。该参数作为初始值传递给内部使用的随机数生成器。如果将其设置为正值,操作符将为每个调用返回相同的结果,并具有相同的参数值。

参数列表:

Contours (in):可用于校准的等高线(图像中提取到轮廓线)
SelectedContours (out):用于校准的等高线(在图像中提取到轮廓线中筛选出符合条件的轮廓线)
Width(in):提取轮廓的图像的宽度
Height(in):提取轮廓的图像的高度
InlierThreshold(in):异常值分类的阈值:
RandSeed(in):随机种子
DistortionModel(in):畸变模式
DistortionCenter(in):决定使用何种方式估计失真中心。有 ‘variable’(默认,适用于图像边缘轮廓线很多或者失真应该很高。否则,在寻找畸变中心时可能会出现不适定性,从而导致不稳定性。)‘adaptive’(如果可以假定畸变中心位于图像中心附近,并且只有很少的等值线可用或其他等值线的位置不好(例如等值线方向相同),则应使用这种方法), ‘fixed’(该方法适用于失真很弱或轮廓线少的情况下,在不好的位置。)
PrincipalPointVar (in):偏差控制,控制畸变中心与图像中心的偏差
CameraParam (out):输出相机内部参数


核心算子二:change_radial_distortion_cam_par( : : Mode, CamParamIn, DistortionCoeffs : CamParamOut) —— 根据指定的径向畸变确定新的相机参数。

参数列表:

Mode (in):模式 ( 注: ‘fixed’ 要比 ‘adaptive’ 稳定)
CamParamIn (in):相机内部参数(原图)
DistortionCoeffs(in):所需的径向扭曲
CamParamOut(out):相机内部参数(已修改)


核心算子三:change_radial_distortion_image(Image, Region : ImageRectified : CamParamIn, CamParamOut : ) —— 改变图像的径向畸变。

change_radial_distortion_image根据摄像机内部参数CamParamIn和CamParamOut对输入图像图像的径向畸变进行改变。使用CamParamOut将位于区域区域内的输出图像的每个像素转换为图像平面,然后使用CamParamIn将其投影为图像的亚像素。通过双线性插值确定得到的灰度值。如果该亚像素在图像之外,则将图像重建中的对应像素设置为“黑色”并从图像域中消除。

参数列表:

Image (in):原始图像
Region (in):成像重建感兴趣的区域。
ImageRectified(out):畸变校正之后的图像
CamParamIn(in):内部相机参数。
CamParamOut(in):内部相机参数(已修改)。
 


戳戳小手帮忙点个免费的赞和关注吧,嘿嘿。
  • 25
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
您可以使用OpenCV提供的相机标定示例程序来进行圆形棋盘格相机标定。在文件夹中,您可以找到名为camera_calibration.cpp的源代码文件,其中包含了OpenCV相机标定的实例程序。您还需要修改in_VID5和VID5两个XML文档来设置标定参数和标定图片路径。此外,OpenCV的相机标定程序还支持Checkerboard(棋盘格)、Symmetric Circle Grid(对称圆网格)和Asymmetric Circle Grid(非对称圆网格)三种标定图案。您可以根据需要选择合适的标定图案进行相机标定。\[1\] 如果您需要生成一张黑白对称圆点的图像作为标定图案,您可以使用以下代码。这段代码使用了OpenCV库来生成一张黑白对称圆点的图像,您可以根据需要修改圆点个数、图片分辨率和图片格式。\[3\] ```cpp #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace cv; using namespace std; #define WINDOW_WIDTH 1200 //定义窗口大小的宏 #define WINDOW_LENTH 1700 #define WINDOW_NAME1 "【绘制图1】" //为窗口标题定义的宏 #define WINDOW_NAME2 "【绘制图2】" //为窗口标题定义的宏 void drawFilledCircle(Mat img, Point center) { int thickness = -1; int lineType = 8; circle(img, center, WINDOW_WIDTH / 12, Scalar(0, 0, 0), thickness, lineType); } int main() { Mat atomImage(WINDOW_WIDTH, WINDOW_LENTH, CV_8UC3, Scalar(255, 255, 255)); for (int i = 180 + WINDOW_WIDTH / 12; i < WINDOW_LENTH; i = i + WINDOW_WIDTH / 4) { for (int j = 50 + WINDOW_WIDTH / 12; j < WINDOW_WIDTH; j = j + WINDOW_WIDTH / 4) { drawFilledCircle(atomImage, cv::Point(i, j)); } } imwrite("symmetricCirclesGridPattern.png", atomImage); imshow(WINDOW_NAME1, atomImage); waitKey(0); return(0); } ``` 这段代码将生成一张名为symmetricCirclesGridPattern.png的黑白对称圆点图像,并显示在窗口中。您可以根据需要修改窗口大小和窗口标题。\[3\] #### 引用[.reference_title] - *1* *3* [MATLAB/OpenCV--基于棋盘格/对称圆点/非对称圆点--相机标定教程](https://blog.csdn.net/m0_51729073/article/details/121268125)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [C++ OpenCV相机标定---实心圆点、棋盘格](https://blog.csdn.net/huhu7777/article/details/126927710)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丶布布

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值