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
相关推荐
时间的情敌14 小时前
Cesium 加载 3D Tiles 倾斜摄影、压平、样式设置(Vue3 实战)
vue.js·3d·cesium
AGI_Eval2 天前
AI 3D生成技术:从“可用”走向“可靠”还有多远?
人工智能·3d
翌日阳3 天前
二十分之一的压缩比:Spatial Vivid 1.0 把 3DGS 全链路参考实现按 MIT 开源了
3d·开源
Dream-Y.ocean4 天前
鸿蒙PC平台宅匠 3D 室内设计适配实战:基于 Electron 壳方案的 Three.js 双渲染引擎与参数化户型编辑器开发
javascript·3d·harmonyos
硕迪科技SOLIDWORKS4 天前
SOLIDWORKS Electrical 2027:从线束定义到2D–3D更改分析
3d·solidworks 202
DolitD4 天前
UE像素流与云渲染技术方案对比分析
3d·云原生·ue5·云计算·图形渲染
tealcwu4 天前
【Unity高级】Unity URP:构建同时支持 2D 与 3D 场景的项目完全指南
3d·unity·游戏引擎
Jmyd01234 天前
文物3D数字化的技术选型指南:从WW/T 0115标准到落地工程,一次讲透采集、建档、管理与展示
3d·系统架构·博物馆·数字展厅·博物馆数字化
Martina_03214 天前
AI生成3D模型一合并网格,材质就串色?用6步检查材质槽、UV与图集重映射
图像处理·人工智能·3d·材质·uv·游戏策划·1024程序员节
鹿野素材屋5 天前
U3D切换场景时候变黑怎么处理
数码相机·3d