halcon3D gen_image_to_world_plane_map的图像高精度拼接技术

基于上一篇文章,对gen_image_to_world_plane_map有了深刻的理解

https://blog.csdn.net/Tianwen_running/article/details/143661157?fromshare=blogdetail\&sharetype=blogdetail\&sharerId=143661157\&sharerefer=PC\&sharesource=Tianwen_running\&sharefrom=from_link

讲一讲基于这个算子的图像拼接技术

一,聊聊原理

1,首先我们在一张平板上准备两张标定图片,确定两个标定图片中心点之间之间的距离是d,就像下面这个样子

2,首先两个相机都是校准过的,对相机的内参是已知的。以左视图为基准,拍两张照片,如下图

3,求出两图的pose1和pose2对图像进行从图像坐标系向世界坐标系的map关系。对于map后的imagemaped图像来说,只要像素大小一致,这两张图像的联系是,他们的0,0点,在世界坐标系下的关系是已知的,那就是在x方向的距离是D.为什么是x,这是标定板照片在制作时定好的,在pose中,反应的中心00点在标定图像的正中心位置。

4,先对image1进行全图片的向世界坐标系的转换,那么问题来了pose2的世界坐标系的map00点应该在什么地方呢

关系式 pose2沿自己的x轴方向移动-d,到达pose1的位置,然后沿向y方向移动pose1设置map00点的距离和x方向移动pose1距离右边框的距离,到达它的世界坐标map00点,有点绕绕的,在代码里看看,结果是这样的

5,在这里参考的是halcon的实例two_camera_calibration.hdev,当然halcon处理的更好,实例真的非常值得学习!

bash 复制代码
dev_update_off ()
ImgPath := '3d_machine_vision/multiple_cameras/'
* 
* Open two windows for the left and the right image.
dev_close_window ()
read_image (Image1, ImgPath + 'camera1_ref')
get_image_size (Image1, Width, Height)
WindowScale := 0.66
dev_open_window (0, 0, Width * WindowScale, Height * WindowScale, 'black', WindowHandle1)
dev_open_window (0, Width * WindowScale + 6, Width * WindowScale, Height * WindowScale, 'black', WindowHandle2)
* 
* Set some parameters for both windows.
dev_set_window (WindowHandle1)
dev_set_color ('green')
dev_set_draw ('margin')
dev_set_line_width (2)
dev_set_part (0, 0, Height - 1, Width - 1)
set_display_font (WindowHandle1, 16, 'mono', 'true', 'false')
* 
dev_set_window (WindowHandle2)
dev_set_color ('green')
dev_set_draw ('margin')
dev_set_line_width (2)
dev_set_part (0, 0, Height - 1, Width - 1)
set_display_font (WindowHandle2, 16, 'mono', 'true', 'false')
* 
* We assume that the two cameras are already calibrated
* (we know the internal camera parameters).
gen_cam_par_area_scan_division (0.01619, -734.789, 7.402e-006, 7.4e-006, 324.911, 256.894, 640, 480, CamParam1)
gen_cam_par_area_scan_division (0.0162584, -763.35, 7.39842e-006, 7.4e-006, 324.176, 245.371, 640, 480, CamParam2)
* 
* Read the images and display them.
read_image (Image1, ImgPath + 'camera1_ref')
read_image (Image2, ImgPath + 'camera2_ref')
dev_set_window (WindowHandle1)
dev_display (Image1)
dev_set_window (WindowHandle2)
dev_display (Image2)
* 
* Prepare the camera calibration.
CaltabName := 'caltab_30mm.descr'
create_calib_data ('calibration_object', 2, 1, CalibDataID)
set_calib_data_calib_object (CalibDataID, 0, CaltabName)
set_calib_data_cam_param (CalibDataID, 0, [], CamParam1)
set_calib_data_cam_param (CalibDataID, 1, [], CamParam2)
* 
* Find and display the calibration plate in the images.
dev_set_window (WindowHandle1)
find_calib_object (Image1, CalibDataID, 0, 0, 0, [], [])
get_calib_data_observ_points (CalibDataID, 0, 0, 0, RowCoord1, ColumnCoord1, Index1, Pose1)
get_calib_data_observ_contours (Caltab1, CalibDataID, 'caltab', 0, 0, 0)
dev_display (Caltab1)
* 
dev_set_window (WindowHandle2)
find_calib_object (Image2, CalibDataID, 1, 0, 0, [], [])
get_calib_data_observ_points (CalibDataID, 1, 0, 0, RowCoord2, ColumnCoord2, Index2, Pose2)
get_calib_data_observ_contours (Caltab2, CalibDataID, 'caltab', 1, 0, 0)
dev_display (Caltab2)
* 
disp_message (WindowHandle1, 'Calibration successful', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle1, 'black', 'true')
stop ()
clear_calib_data (CalibDataID)
* 
* Determine the offset between the calibration plate surface
* and the object surface
ThicknessCaliper := 2.9 / 1000.0
ThicknessPlate := 5.65 / 1000.0
****DiffHeight:=0.0029
DiffHeight := ThicknessPlate - ThicknessCaliper
DistancePlates := 0.06488
* 
*马赛克像素的大小0.0001m.
PixelSize := 0.0001
******将pose的00点,移动到像素00点对应的世界坐标系下
image_points_to_world_plane (CamParam1,Pose1, 0, 0, 'm', X, Y)
set_origin_pose (Pose1,X, Y, 0, PoseNewOrigin)
get_image_size (Image1, Width2, Height2)
image_points_to_world_plane (CamParam2, Pose1, Height2, Width2, 'm', X2, Y2)
widthx:=round((X2-X)/0.0001)
widthy:=round((Y2-Y)/0.0001)
gen_image_to_world_plane_map (Map, CamParam1, PoseNewOrigin,Width2,  Height2,widthx, widthy, PixelSize , 'bilinear')
map_image (Image1, Map, ImageMapped2)

hom_mat3d_identity (HomMat3DIdentity1)
***两个标定板中心距离是DistancePlates := 0.06488
hom_mat3d_translate_local (HomMat3DIdentity1, -DistancePlates, 0, 0, HomMat3DTranslate)
***向世界坐标系转换中,第二章照片的00点位置,应该在左照片的右下角处
***移到pose1的00点后,再向x方向移动 X2,Y2的距离
hom_mat3d_translate_local (HomMat3DTranslate, X2,Y, 0, HomMat3DTranslate1)

****对pose的中心点进行移动
pose_to_hom_mat3d (Pose2, HomMat3D)
hom_mat3d_compose (HomMat3D, HomMat3DTranslate1, HomMat3DCompose)
***再转回pose
hom_mat3d_to_pose (HomMat3DCompose, Pose2Origin)

get_image_size (Image2, Width3, Height3)
gen_image_to_world_plane_map (Map1, CamParam2, Pose2Origin, Width3, Height3, widthx, widthy, PixelSize, 'bilinear')
map_image (Image2, Map1, ImageMapped3)

concat_obj (ImageMapped2, ImageMapped3, ObjectsConcat1)
tile_images (ObjectsConcat1, TiledImage1, 2, 'horizontal')

***目测看看两个中心的距离 289,396和289,1045
***a:=0.069
a:=(1045-396)*0.0001
相关推荐
Dave.B1 天前
用【vtk3DLinearGridCrinkleExtractor】快速提取3D网格相交面
算法·3d·vtk
中科米堆1 天前
中科米堆CASAIM自动化三维检测-0.02mm计量级精度产品尺寸快速检测
人工智能·3d·3d全尺寸检测
中科米堆1 天前
自动化大尺寸批量3D检测,自动化三维扫描系统实现钢板支架在线检测-中科米堆CASAIM
运维·3d·自动化·3d全尺寸检测
CreasyChan1 天前
3D游戏数学基础指南
游戏·3d·unity·数学基础
jingling5551 天前
Mark3D | 用 Mars3D 实现一个炫酷的三维地图
前端·javascript·3d·前端框架·html
Aevget2 天前
可视化工具LightningChart JS v8.1 重磅更新:热力图与 3D 可视化能力双提升!
javascript·3d·信息可视化·数据可视化·lightningchart
这张生成的图像能检测吗2 天前
Wonder3D: 跨域扩散的单图像3D重建技术
pytorch·深度学习·机器学习·计算机视觉·3d·三维重建·扩散模型
不爱学英文的码字机器2 天前
【征文计划】从零开始XR开发:基于Rokid空间计算平台打造《光之岛》3D游戏
3d·xr·空间计算
PHOSKEY2 天前
3D工业相机量化管控耳机充电弹针关键尺寸
数码相机·3d
二狗哈2 天前
Cesium快速入门26:加载渲染GeoJson数据
3d·webgl·cesium·地图可视化