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
相关推荐
总要学点什么5 小时前
第63篇:3DTiles-大雁塔模型——190 块瓦片不是八叉树,抬高的却是球心那条法线
3d·数据挖掘·数据分析·gis·webgl
云飞云共享云桌面1 天前
设计师共享单台图形服务器,解决 SolidWorks大装配卡顿难题
运维·服务器·3d·自动化·电脑·制造
天桥下的卖艺者1 天前
R语言使用ggcube包轻松绘制文章中的各类3D图形
开发语言·3d·r语言
炽橙超真云1 天前
2D 工程图纸如何自动转成可编辑 3D 模型?拆解读图与建体两条技术路径(DXF/DWG/PDF 到 STEP)
算法·3d·工业智能·工业ai
3D阅阅三维模型轻量化及浏览平台2 天前
3D 阅阅:机加工与模具厂的智能看图报价实战
3d·机械加工·机加工·钣金加工·模具加工
福大大架构师每日一题2 天前
ComfyUI v0.40.0发布:资产系统、原生 LoRA 堆栈、Qwen 3.5、3D 输出、相机节点与多项合作节点全面更新
数码相机·3d
LuminWave2 天前
洛微科技重磅发布DM-Mini 3D ToF相机:以超近距精准感知,赋能机器人灵巧操作
科技·3d·机器人
Mark White2 天前
ICCV 2019【从颜色科学到相机】06_相机为什么有自己的“味道”?色调映射、3D LUT 与 JPEG
数码相机·3d
Jmyd01233 天前
文物3D扫描采集系统选型与集成:固定+手持双链路技术方案
3d·文物修复·文物数字化·文物建模
博图光电3 天前
笔记本键盘漏光缺陷检测
人工智能·数码相机·3d·自动化