当前位置: 首页 > news >正文

Halcon双相机单标定板标定实现拼图

1.Halcon图像拼接算法在之前的文章里也写过,主要是硬拼接和特征点拼接两种方式,今天增加另一种拼接图像的方式。应用场景是多个相机联合一起拍大尺寸的物体,并且相机视野之间存在重叠区域。通过在同一个标定板上面标定,计算两个相机之间位相对外参矩阵实现拼接。
2.代码分析

dev_update_off ()
*

  • Path to the calibration and object images.
    ImagePath := ‘3d_machine_vision/calibrated_mosaic/’
  • Display workflow explanation text.
    dev_close_window ()
    dev_open_window (0, 0, 600, 300, ‘black’, WindowHandle1)
    set_display_font (WindowHandle1, 16, ‘mono’, ‘true’, ‘false’)
    dev_disp_workflow_text ()
    stop ()
  • Display calibration explanation text.
    dev_clear_window ()
    dev_disp_calibration_text ()
    stop ()

dev_close_window ()
dev_open_window (0, 0, 600, 480, ‘black’, WindowHandle1)
dev_open_window (0, 605, 600, 480, ‘black’, WindowHandle2)
set_display_font (WindowHandle1, 16, ‘mono’, ‘true’, ‘false’)
set_display_font (WindowHandle2, 16, ‘mono’, ‘true’, ‘false’)
*


  • *********** Step 1: Calibration of the cameras ***********

  • Number of calibration images.
    NumCalibImages := 10
  • 从每个摄像头读取一张图像,以获得摄像头的宽度和高度。
    read_image (ImageCam1, ImagePath + ‘/calib_cam_1_01’)
    read_image (ImageCam2, ImagePath + ‘/calib_cam_2_01’)
    get_image_size (ImageCam1, WidthCam1, HeightCam1)
    get_image_size (ImageCam2, WidthCam2, HeightCam2)
  • 设置内部相机参数的初始值。
    gen_cam_par_area_scan_division (0.012, 0, 4.4e-6, 4.4e-6, WidthCam1 / 2, HeightCam1 / 2, WidthCam1, HeightCam1, StartCamParam1)
    gen_cam_par_area_scan_division (0.012, 0, 4.4e-6, 4.4e-6, WidthCam2 / 2, HeightCam2 / 2, WidthCam2, HeightCam2, StartCamParam2)
  • 创建标定模型,并设置参数,此模型同时可以校准两个相机
    create_calib_data (‘calibration_object’, 2, 1, CalibDataID)
    set_calib_data_cam_param (CalibDataID, 0, [], StartCamParam1)
    set_calib_data_cam_param (CalibDataID, 1, [], StartCamParam2)
    set_calib_data_calib_object (CalibDataID, 0, ‘calplate_160mm.cpd’)
  • 依次访问两个相机的标定板图片,进行标定操作
    for I := 0 to NumCalibImages - 1 by 1
    • Read the calibration images.
      read_image (ImageCam1, ImagePath + ‘/calib_cam_1_’ + (I + 1)KaTeX parse error: Double subscript at position 56: …+ '/calib_cam_2_̲' + (I + 1)‘02d’)
    • Find the calibration plate and store observations
    • in the calibration data model.
      find_calib_object (ImageCam1, CalibDataID, 0, 0, I, [], [])
      get_calib_data_observ_contours (ContoursCam1, CalibDataID, ‘marks’, 0, 0, I)
      find_calib_object (ImageCam2, CalibDataID, 1, 0, I, [], [])
      get_calib_data_observ_contours (ContoursCam2, CalibDataID, ‘marks’, 1, 0, I)
    • Display calibration images and observed contours.
      dev_set_window (WindowHandle1)
      dev_display (ImageCam1)
      dev_display (ContoursCam1)
      dev_disp_text (‘Image ’ + (I + 1) + ‘/’ + NumCalibImages + ’ (Camera 1)’, ‘window’, ‘top’, ‘left’, ‘black’, [], [])
      dev_set_window (WindowHandle2)
      dev_display (ImageCam2)
      dev_display (ContoursCam2)
      dev_disp_text (‘Image ’ + (I + 1) + ‘/’ + NumCalibImages + ’ (Camera 2)’, ‘window’, ‘top’, ‘left’, ‘black’, [], [])
      disp_continue_message (WindowHandle2, ‘black’, ‘true’)
      stop ()
      endfor

*同时校准两个摄像头.
calibrate_cameras (CalibDataID, Errors)
dev_set_window (WindowHandle1)
dev_disp_text (‘Calibration successful’, ‘window’, ‘top’, ‘left’, ‘green’, [], [])
dev_set_window (WindowHandle2)
dev_disp_text (‘Calibration successful’, ‘window’, ‘top’, ‘left’, ‘green’, [], [])
disp_continue_message (WindowHandle2, ‘black’, ‘true’)
stop ()
*


  • ******************* Step 2: Mosaicking *******************

  • Display mosaicking explanation text.
    dev_close_window ()
    dev_close_window ()
    dev_open_window (0, 0, 600, 300, ‘black’, WindowHandle1)
    set_display_font (WindowHandle1, 16, ‘mono’, ‘true’, ‘false’)
    dev_disp_mosaicking_text ()
    stop ()
  • Number of objects.
    NumObjects := 2
  • Number of images per object.
    NumObjImages := 2
  • 获取两个相机各自的标定好的参数,相机内参
    get_calib_data (CalibDataID, ‘camera’, 0, ‘params’, CamParam1)
    get_calib_data (CalibDataID, ‘camera’, 1, ‘params’, CamParam2)
  • 获取相对于第一个相机(参考相机)的位姿
    get_calib_data (CalibDataID, ‘calib_obj_pose’, [0,0], ‘pose’, Pose1)
    *设置标定板厚度4mm,注意算子需要用的单位是米m
    set_origin_pose (Pose1, 0, 0, 0.004, Pose1)
  • 获取第二台相机相对于第一台相机的位姿.
    get_calib_data (CalibDataID, ‘camera’, 1, ‘pose’, RelPose2)
    *为了获得第二个相机的绝对姿态,它的相对姿态需要
    *以被反转并与第一相机的绝对姿态相结合。
    pose_invert (RelPose2, RelPose2Inverted)
    pose_compose (RelPose2Inverted, Pose1, Pose2)

*设置目标图像宽度、高度和比例,以便整个对象
*映射后图像拟合良好。
TargetWidth := 1340
TargetHeight := 800
*像素当量(1颗像素0.0002m),注意单位是m/pixel
Scale := 0.0002

  • 设置区域,可以裁剪掉有黑边的图像区域
    Borders := [125,110,665,1222]

*为了映射对象图像,需要校正相机的姿态
*再次取决于物体的厚度。这里我们使用两个不同的对象:
*一把厚度约为2.5mm的尺子和一本薄薄的小册子,可以
*近似为0mm厚度。
HeightCorrections := [-0.0025,0]
*
dev_close_window ()
dev_open_window (0, 0, 600, 480, ‘black’, WindowHandle1)
dev_open_window (0, 605, 600, 480, ‘black’, WindowHandle2)
dev_open_window (535, 0, 740, 360, ‘black’, WindowHandle3)
set_display_font (WindowHandle1, 16, ‘mono’, ‘true’, ‘false’)
set_display_font (WindowHandle2, 16, ‘mono’, ‘true’, ‘false’)
set_display_font (WindowHandle3, 16, ‘mono’, ‘true’, ‘false’)

for OIdx := 0 to NumObjects - 1 by 1
* 设置矫正图像原点位置和标定板厚度
set_origin_pose (Pose1, -0.14, -0.07, HeightCorrections[OIdx], WorldPose1)
set_origin_pose (Pose2, -0.14, -0.07, HeightCorrections[OIdx], WorldPose2)
*
* 生成矫正矩阵
gen_image_to_world_plane_map (Map1, CamParam1, WorldPose1, WidthCam1, HeightCam1, TargetWidth, TargetHeight, Scale, ‘bilinear’)
gen_image_to_world_plane_map (Map2, CamParam2, WorldPose2, WidthCam1, HeightCam1, TargetWidth, TargetHeight, Scale, ‘bilinear’)
*
* 矫正图像
for IIdx := 1 to NumObjImages by 1
ObjImageIdx := 2 * OIdx + IIdx
read_image (ImageCam1, ImagePath + ‘/obj_cam_1_’ + ObjImageIdxKaTeX parse error: Double subscript at position 62: …h + '/obj_cam_2_̲' + ObjImageIdx’02d’)
*
* Display input images and camera poses.
dev_set_window (WindowHandle1)
dev_display (ImageCam1)
dev_disp_text (‘Camera 1 image’, ‘window’, ‘top’, ‘left’, ‘black’, [], [])
disp_3d_coord_system (WindowHandle1, CamParam1, Pose1, 0.05)
dev_set_window (WindowHandle2)
dev_display (ImageCam2)
dev_disp_text (‘Camera 2 image’, ‘window’, ‘top’, ‘left’, ‘black’, [], [])
disp_3d_coord_system (WindowHandle2, CamParam2, Pose2, 0.05)
*
* 通过将图像映射到世界坐标系来优化图像。
map_image (ImageCam1, Map1, ImageWorld1)
map_image (ImageCam2, Map2, ImageWorld2)
*
* 将映射的图像拼接在一起。
get_domain (ImageWorld1, Domain1)
get_domain (ImageWorld2, Domain2)
intersection (Domain1, Domain2, RegionIntersection)
paint_region (RegionIntersection, ImageWorld1, ImageWorld1Blackended, 0, ‘fill’)
full_domain (ImageWorld1Blackended, ImagePart1)
full_domain (ImageWorld2, ImagePart2)
add_image (ImagePart1, ImagePart2, ImageFull, 1, 0)
*
* Rotate image and remove the black borders for display.
rotate_image (ImageFull, ImageRotated, 12, ‘constant’)
gen_rectangle1 (RectangleDomain, Borders[0], Borders[1], Borders[2], Borders[3])
reduce_domain (ImageRotated, RectangleDomain, ImageReduced)
crop_domain (ImageReduced, ImageReduced)
mirror_image (ImageReduced, ImageReduced, ‘row’)
mirror_image (ImageReduced, ImageResult, ‘column’)
*
* Display the result image.
dev_set_window (WindowHandle3)
dev_display (ImageResult)
dev_disp_text (‘Result image’, ‘window’, ‘top’, ‘left’, ‘black’, [], [])
if (ObjImageIdx < NumObjects * NumObjImages)
disp_continue_message (WindowHandle3, ‘black’, ‘true’)
stop ()
else
dev_disp_text (‘End of program’, ‘window’, ‘bottom’, ‘right’, ‘black’, [], [])
endif
endfor
endfor
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

http://www.xdnf.cn/news/1128565.html

相关文章:

  • Java线程池深度解析与Spring Boot实战指南
  • resources为什么是类的根目录
  • 策略设计模式分析
  • AI辅助Python编程30天速成
  • 死锁问题以及读写锁和自旋锁介绍【Linux操作系统】
  • LeetCode|Day13|88. 合并两个有序数组|Python刷题笔记
  • MySQL数学函数
  • HALCON+PCL混合编程
  • 从抽象函数到可计算导数 ——SymPy 中占位、求导、代入的完整闭环
  • JVM——编译执行于解释执行的区别是什么?JVM使用哪种方式?
  • K型热电偶电动势以及温度对照表
  • 从基础到进阶:MyBatis-Plus 分页查询封神指南
  • BPE(字节对编码)和WordPiece 是什么
  • [AI-video] Web UI | Streamlit(py to web) | 应用配置config.toml
  • Android 图片压缩
  • Spring应用抛出NoHandlerFoundException、全局异常处理、日志级别
  • 前端开发数据缓存方案详解
  • 1.easypan-登录注册
  • git起步
  • Jfinal+SQLite java工具类复制mysql表数据到 *.sqlite
  • 同济医院R语言训练营第三期开讲!上交大张维拓老师主讲
  • 2025最新国产用例管理工具评测:Gitee Test、禅道、蓝凌测试、TestOps 哪家更懂研发协同?
  • 希尔排序:突破传统排序的边界
  • 22.计算指定范围内数字的幂次和
  • StampedLock分析
  • 基于cornerstone3D的dicom影像浏览器 第二章,初始化页面结构
  • 亚矩阵云手机:破解 Yandex 广告平台多账号风控难题的利器
  • 跨平台游戏引擎 Axmol-2.7.1 发布
  • APP端定位实现(uniapp Vue3)(腾讯地图)
  • Ext系列文件系统知识点