Halcon 4点单标相机外参

1. 单标外参使用背景

  • 如果摄像机系统没有变化,只是测量面发生了移动或旋转,此时重标相机外参可以解决问题,这种方法可以解决斜测的问题。

2. 主要函数:

vector_to_pose( : : WorldX, WorldY, WorldZ, ImageRow, ImageColumn,CameraParam, Method, QualityType : Pose, Quality)

  • //功能:利用世界坐标和像素坐标之间的关系计算出摄像机在世界坐标系中的姿态
  • //WorldX, WorldY, WorldZ:世界坐标
  • //mageRow, ImageColumn:像素坐标
  • //CameraParam:内参
  • //Method, QualityType :计算姿态方法,质量评估方法
  • //Pose, Quality:返回姿态,质量

3. 代码

  • 下面这两种情况是等价的,都属于斜测,用相机测量斜面上的目标。由两种方法可以解决此问题,透视变换法和单标法,这里先介绍单标法:
    在这里插入图片描述
  • 资源下载地址:
    链接:https://pan.baidu.com/s/1DUQJjr9ntyKGb_etGs57fQ
    提取码:2u20

halcon代码实现4点单标相机外参

* 1.读入已经标定好的相机内参
read_cam_par ('./campar.dat', CameraParam)
* 2.读入标定外参使用的图像(斜面上的标定板)
read_image (Image, './斜侧标定板图片.jpg')
* 3.处理图像,得到至少4个Mark点
binary_threshold (Image, Region, 'max_separability', 'dark', UsedThreshold)
connection (Region, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, ['area','row','column'], 'and', [0,372.22,575.99], [10113.8,574.44,868.94])
sort_region (SelectedRegions, SortedRegions, 'character', 'true', 'row')
area_center (SortedRegions, Area, Row, Column)
* 4.手动写入4个mark点的世界坐标
X:=[0,0.0037,0,0.0037]
Y:=[0,0,0.0037,0.0037]
Z:=[0,0,0,0]
* 5.标定相机外参
vector_to_pose (X, Y, Z, Row, Column, CameraParam, 'iterative', 'error', Pose, Quality)
write_pose (Pose, './4Pointcampose.dat')

*************至此,4点单标外参已经全部完成**********************************
*************以下使用一维测量标定板外边框尺寸来验证相机外参是否正确************
dev_display (Image)
Row:=694
Column:=987
Angle:=rad(90)//选择编写较大的一条边测量
Length1:=300
Length2:=10
get_image_size (Image, Width, Height)
gen_measure_rectangle2 (Row, Column, Angle, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle)
gen_rectangle2 (Rectangle,Row, Column, Angle, Length1, Length2)
measure_pos (Image, MeasureHandle, 2, 30, 'all', 'all', RowEdge, ColumnEdge, Amplitude, Distance)
dev_set_color ('green')
dev_set_draw ('margin')
dev_set_line_width (3)
dev_get_window (WindowHandle)
set_display_font (WindowHandle, 26, 'mono', 'true', 'false')
gen_empty_obj (ContoursObject)

dev_display (Image)
if(|RowEdge|==4)
       gen_contour_polygon_xld (Contour1, \
                  [RowEdge[0]+Length2*cos(Angle),RowEdge[0]-Length2*cos(Angle)], \
                  [ColumnEdge[0]+Length2*sin(Angle),ColumnEdge[0]-Length2*sin(Angle)])       
       gen_contour_polygon_xld (Contour1, \
                  [RowEdge[3]+Length2*cos(Angle),RowEdge[3]-Length2*cos(Angle)], \
                  [ColumnEdge[3]+Length2*sin(Angle),ColumnEdge[3]-Length2*sin(Angle)])       

       dev_display (ContoursObject)
       
       image_points_to_world_plane (CameraParam, Pose, RowEdge, ColumnEdge, 'mm', X1, Y1)
       distance_pp (X1[0], Y1[0], X1[3], Y1[3], Distance1)
       distance_pp (RowEdge[0], ColumnEdge[0], RowEdge[3], ColumnEdge[3], Distance2)
       disp_line (WindowHandle, RowEdge[0], ColumnEdge[0], RowEdge[3], ColumnEdge[3])
       disp_message (WindowHandle, 'L1='+Distance1, 'image', 12, 12, 'black', 'true')
       disp_message (WindowHandle, 'L2='+Distance2, 'image', 12+100, 12, 'black', 'true')
       disp_message (WindowHandle, '像素当量='+Distance1/Distance2, 'image', 12+200, 12, 'black', 'true')
endif
stop()

dev_display (Image)
Row:=633
Column:=956
Angle:=rad(0)
Length1:=300
Length2:=10

gen_measure_rectangle2 (Row, Column, Angle, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle)
gen_rectangle2 (Rectangle,Row, Column, Angle, Length1, Length2)
measure_pos (Image, MeasureHandle, 2, 30, 'all', 'all', RowEdge, ColumnEdge, Amplitude, Distance)

dev_display (Image)

if(|RowEdge|==4)  
       gen_contour_polygon_xld (Contour1, \
                  [RowEdge[0]+Length2*cos(Angle),RowEdge[0]-Length2*cos(Angle)], \
                  [ColumnEdge[0]+Length2*sin(Angle),ColumnEdge[0]-Length2*sin(Angle)])       
       gen_contour_polygon_xld (Contour1, \
                  [RowEdge[3]+Length2*cos(Angle),RowEdge[3]-Length2*cos(Angle)], \
                  [ColumnEdge[3]+Length2*sin(Angle),ColumnEdge[3]-Length2*sin(Angle)])       

       dev_display (ContoursObject)
       
       image_points_to_world_plane (CameraParam, Pose, RowEdge, ColumnEdge, 'mm', X1, Y1)
       distance_pp (X1[0], Y1[0], X1[3], Y1[3], Distance1)
       distance_pp (RowEdge[0], ColumnEdge[0], RowEdge[3], ColumnEdge[3], Distance2)
       
       disp_line (WindowHandle, RowEdge[0], ColumnEdge[0], RowEdge[3], ColumnEdge[3])
       disp_message (WindowHandle, 'L1='+Distance1, 'image', 12, 12, 'black', 'true')
       disp_message (WindowHandle, 'L2='+Distance2, 'image', 12+100, 12, 'black', 'true')
       disp_message (WindowHandle, '像素当量='+Distance1/Distance2, 'image', 12+200, 12, 'black', 'true')
endif

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MechMaster

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值