1_4 3D点与2D匹配计算相机pose

本文介绍了计算相机位姿的两种主要方法:直接法,如OpenCV的solvePnP函数,以及基于BA(BundleAdjustment)的优化方法,包括高斯-牛顿法和g2o库的应用。通过最小化误差来优化相机姿态,展示了从像素坐标到相机坐标转换的过程,并提供了相关代码示例。

        对于已知3D点和2D点的匹配关系,进而计算相机位姿的方法有两大类,一类是直接求解法,包括DLS、PNP等;一类是基于BA的优化方法;

        1、直接法

        直接法可以利用opencv中已有的函数solvePnP(pts_3d, pts_2d, K, Mat(), r, t, false)进行求解;

        2、BA的方法

        对于BA方法实际上是通过优化最小误差进行实现,而优化方法可以有多种方式,包括采用高斯-牛顿法、g2o、ceres等工具库,这里介绍高斯-牛顿法和g2o两种方法;

        无论哪种方法首先需要给出优化误差,具体如下:

\xi ^{*}=argmin\frac{1}{2}\sum_{i=1}^{n}\left \| p_{i}-\frac{1}{s_{i}}Kexp(\xi^{\wedge})P_{i} \right \|_{2}^{2}

为了简化计算,这里将exp(\xi ^{\wedge})P_{i}=P^{'}

        考虑单个投影点误差:e_{i}=u_{i}-\frac{1}{s_{i}}Kexp(\xi ^{\wedge})P_{i}

        对其线性化后:e_{i}(x+\Delta x)\approx e_{i}(x)+J(x)\Delta x

        雅可比的形式如下:\frac{\partial e}{\partial \delta \xi}=\lim_{\delta \xi \to 0} \frac{e(\delta \xi \bigoplus \xi)}{\delta \xi}=\frac{\partial e}{\partial P^{'}} \frac{\partial P^{'}}{\partial \delta \xi}

        这里的P'为P在相机坐标系下的坐标:P^{'}=(exp(\xi ^{\wedge})P)_{1:3}=[X^{'},Y{'},Z{'}]^{T}

        对P'进行投影su=KP^{'}

        这里\begin{bmatrix} su &\\sv&\\s \end{bmatrix} =\begin{bmatrix} f_{x}&0 &c_{x} \\ 0& f_{x} &c_{y} \\ 0 &0 &1 \end{bmatrix}\begin{bmatrix} X^{'}\\ Y^{'}\\ Z^{'} \end{bmatrix}

        u=f_{x}\frac{X^{'}}{Z^{'}}+c_{x}\\ v=f_{y}\frac{Y^{'}}{Z^{'}}+c_{y}

        

可以结合 `render_object_model_3d` 函数将3D对象模型渲染为2D图像,再使用2D模板匹配的方法来实现零件3D数模2D照片的匹配。以下是一个示例程序: ```python import halcon as ha # 读取2D照片 read_image(Image, './your_2d_photo.tif') # 定义ROI区域 gen_rectangle1(ROI_0, 420.708, 55.4103, 2606.9, 1005.36) area_center(ROI_0, Area2, Row3, Column3) reduce_domain(Image, ROI_0, ImageReduced1) crop_domain(ImageReduced1, ImagePart) get_image_size(ImagePart, Width2, Height2) # 创建2D模板 create_shape_model(ImagePart, 'auto', -0.39, 0.79, 'auto', 'auto', 'use_polarity', 10, 5, ModelID) get_shape_model_contours(ModelContours1, ModelID, 1) vector_angle_to_rigid(0, 0, 0, Row3, Column3, 0, HomMat2D2) dev_display(Image) affine_trans_contour_xld(ModelContours1, ContoursAffineTrans1, HomMat2D2) # 读取3D数模 read_object_model_3d('your_3d_model.stl', 'm', [], [], ObjectModel3D) # 定义相机参数位姿 CamParam = [2000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] Pose = [0, 0, 0, 0, 0, 0, 'tu'] # 渲染3D数模为2D图像 render_object_model_3d(ObjectModel3D, CamParam, Pose, [], [], Image) # 在渲染的2D图像中进行模板匹配 find_shape_model(Image, ModelID, -0.39, 0.79, 0.3, 1, 0.5, 'least_squares', 0, 0.9, Row2, Column2, Angle, Score) # 显示匹配结果 vector_angle_to_rigid(0, 0, 0, Row2, Column2, Angle, HomMat2D3) dev_display(Image) gen_cross_contour_xld(Cross1, Row2, Column2, 116, 0.78) affine_trans_contour_xld(ModelContours1, ContoursAffineTrans, HomMat2D3) ``` 上述代码首先读取2D照片并创建2D模板,然后读取3D数模,使用 `render_object_model_3d` 函数将3D数模渲染为2D图像,最后在渲染的2D图像中进行模板匹配并显示匹配结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值