五.HALCON摄像机标定

1.read_cam_par( : :CamParFile: CameraParam)

从文件夹中读取相机的内参数。

2.disp_caltab( : :WindowHandle,CalTabDescrFile,CameraParam,CaltabPose,ScaleFac: )

利用相机内外参数,把标定板模型投影到图像平面,显示标定点和连接线,X,Y轴也被显示出来。

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

计算世界坐标和图像坐标之间关系的绝对位姿参数。其中世界坐标至少选择不在同一条直线上的三个点。

世界坐标上的点如果在一个平面上,应该选择'planar_analytic'作为Method的参数。输出位姿和位姿质量。

4.write_pose( : : Pose,PoseFile: )

把位姿写入TXT文件。

5.get_mbutton( : :WindowHandle: Row,Column,Button)

返回鼠标点击的图像点像素坐标,以及鼠标按钮值,左键0,中间键2,右键4.

6.image_points_to_world_plane( : :CameraParam,WorldPose,Rows,Cols,Scale: X,Y)

把图像坐标转化成Z=0平面的世界坐标,输出为世界坐标的X,Y

7.pose_to_hom_mat3d( : :Pose: HomMat3D)

把3D位姿转化成齐次变换矩阵。(即可实现三维的空间坐标系转换为二维的图像坐标系之间的对应关系)

8.affine_trans_point_3d( : : HomMat3D,Px,Py,Pz: Qx,Qy,Qz)

进行两个坐标系之间的3D坐标的仿射变换。

       / Qx \             / Px \

 | Qy | = HomMat3D * | Py | 
 | Qz | | Pz | 
 \ 1 / \ 1 / 
9.project_3d_point( : : X, Y, Z, CameraParam : Row, Column) 
把3D点映射到图像坐标系,返回图像坐标系中该点的行列坐标。 (显然X,Y,Z均是相机坐标系下的的坐标,它是由世界坐标系经过相机外参映射得到的。CareraParm为相机内参,由它可得到相机坐标系在图像坐标系下的对应的点的坐标,即行列坐标)
  

10.smallest_rectangle2(Regions: : : Row,Column,Phi,Length1,Length2)

返回包含一个区域的最小环绕矩形。

11.gen_measure_rectangle2( : :Row,Column,Phi,Length1,Length2,Width,Height,Interpolation: MeasureHandle)

返回和矩形边垂直的边缘。

12.measure_pairs(Image: : MeasureHandle,Sigma,Threshold,Transition,Select: RowEdgeFirst,ColumnEdgeFirst,AmplitudeFirst,RowEdgeSecond,ColumnEdgeSecond,AmplitudeSecond,IntraDistance,InterDistance)

抽取和矩形边垂直的边缘对。返回各测量对之间的距离。

13.close_measure( : :MeasureHandle: )

删除测量句柄。

14.gen_region_polygon_filled( :Region: Rows,Columns: )

创建多边形填充区域,输出为一个区域。

15.gen_region_polygon_filled( :Region: Rows,Columns: )

提取直线极其宽度,输出为XLD形式数组。

16.hom_mat3d_compose( : : HomMat3DLeft,HomMat3DRight: HomMat3DCompose)

输出两个齐次矩阵的乘积。

17.hom_mat3d_translate_local( : : HomMat3D,Tx,Ty,Tz: HomMat3DTranslate)

相对于新坐标系统,增加一个平移量到齐次矩阵HomMat3D中,输出为新的齐次矩阵。

18.hom_mat3d_rotate_local( : : HomMat3D,Phi,Axis: HomMat3DRotate)

相对于新坐标系统,增加一个绕着某个坐标轴的旋量到齐次矩阵HomMat3D中,输出为新的齐次矩阵。

17.contour_to_world_plane_xld(Contours: ContoursTrans: CameraParam,WorldPose,Scale: )

转换XLD轮廓进入Z=0的世界坐标平面,输出形式为xld_cont(-array) object

18.get_contour_xld(Contour: : : Row,Col)

返回轮廓点的行列坐标。

19.tuple_mean( : : Tuple: Mean)

返回数组的平均值

20.map_image(Image,Map: ImageMapped: : )

对图像进行校正,输出为校正后的图像。

附:摄像机校正和利用校正后的结果进行测量以及图像校正的程序段

 

* Attention:
* This program reads the interior camera parameters from the file
* 'camera_parameters.dat', which, e.g., could be generated by the program
* 'camera_calibration_interior.hdev'
*
ImgPath := '3d_machine_vision/calib/'
dev_close_window ()
dev_open_window (0, 0, 652, 494, 'black', WindowHandle)
dev_update_off ()
dev_set_draw ('margin')
dev_set_line_width (1)
set_display_font (WindowHandle, 14, 'courier', 'true', 'false')
* Read the interior camera parameters from file
read_cam_par ('camera_parameters.dat', CamParam)
*
* Determine the exterior camera parameters and world coodinates from image points
*
* The exterior camera parameters can be determined from an image, where the
* calibration plate is positioned directly on the measurement plane
read_image (Image, ImgPath+'calib_11')
dev_display (Image)
* parameter settings for find_caltab and find_marks_and_pose
SizeGauss := 3
MarkThresh := 200
MinDiamMarks := 10
StartThresh := 128
DeltaThresh := 10
MinThresh := 18
Alpha := 0.9
MinContLength := 15
MaxDiamMarks := 100
CaltabName := 'caltab_30mm.descr'
find_caltab (Image, Caltab, CaltabName, SizeGauss, MarkThresh, MinDiamMarks)
dev_set_color ('green')
dev_display (Caltab)
* Here, the final camera parameters are already known and can be used instead of the starting values
* used in the program 'camera_calibration_interior.hdev'
find_marks_and_pose (Image, Caltab, CaltabName, CamParam, StartThresh, DeltaThresh, MinThresh, Alpha, MinContLength, MaxDiamMarks, RCoord, CCoord, PoseForCalibrationPlate)
dev_set_color ('red')
disp_caltab (WindowHandle, CaltabName, CamParam, PoseForCalibrationPlate, 1)
dev_set_line_width (3)
disp_circle (WindowHandle, RCoord, CCoord, gen_tuple_const(|RCoord|,1.5))
* caltab_points (CaltabName, X, Y, Z)
* camera_calibration (X, Y, Z, RCoord, CCoord, CamParam, InitialPoseForCalibrationPlate, 'pose', CamParamUnchanged, FinalPoseFromCalibrationPlate, Errors)
* To take the thickness of the calibration plate into account, the z-value
* of the origin given by the camera pose has to be translated by the
* thickness of the calibration plate.
* Deactivate the following line if you do not want to add the correction.
set_origin_pose (PoseForCalibrationPlate, 0, 0, 0.00075, PoseForCalibrationPlate)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* Alternatively, the exterior camera parameters can  be determined from
* at least three point correspondances between the WCS and the pixel coordinate system
read_image (Image, ImgPath+'caliper_01')
dev_display (Image)
* Set the world coordinates of three points on the rule
X := [0,50,100,80]
Y := [5,0,5,0]
Z := [0,0,0,0]
* Set the respective image plane coordinates of the three points
RCoord := [414,227,85,128]
CCoord := [119,318,550,448]
*
disp_cross (WindowHandle, RCoord, CCoord, 6, 0)
* create_pose (-50, 25, 400, 0, 0, -30, 'Rp+T', 'gba', 'point', InitialPose)
vector_to_pose (X, Y, Z, RCoord, CCoord, CamParam, 'iterative', 'error', FinalPose, Errors)
* camera_calibration (X, Y, Z, RCoord, CCoord, CamParam, InitialPose, 'pose', CamParamUnchanged, FinalPose, Errors)
write_pose (FinalPose, 'pose_from_three_points.dat')
* Now, transform a point measured interactively into the WCS
dev_update_window ('on')
dev_display (Image)
while (1)
    disp_message (WindowHandle, 'Measure one point: left mouse button', 'window', 12, 12, 'red', 'false')
    disp_message (WindowHandle, 'Exit measure mode: right mouse button', 'window', 36, 12, 'red', 'false')
    get_mbutton (WindowHandle, Row, Column, Button)
    if (Button = 4)
        break
    endif
    dev_display (Image)
    dev_set_color ('green')
    disp_cross (WindowHandle, Row, Column, 6, 0)
    image_points_to_world_plane (CamParam, FinalPose, Row, Column, 1, X1, Y1)
    disp_message (WindowHandle, 'X = '+X1, 'window', 320, 400, 'red', 'false')
    disp_message (WindowHandle, 'Y = '+Y1, 'window', 340, 400, 'red', 'false')
endwhile
* Apply the measure tool and transform the resulting point coordinates
* into the WCS
dev_set_color ('red')
dev_display (Image)
* Set the world coordinates of four points defining a ROI for the measure tool
ROI_X_WCS := [-2,-2,112,112]
ROI_Y_WCS := [0,0.5,0.5,0]
ROI_Z_WCS := [0,0,0,0]
* Determine the transformation matrix from the WCS into the CCS
pose_to_hom_mat3d (FinalPose, CCS_HomMat_WCS)
* Transform the point coordintes into the image coordinate system
affine_trans_point_3d (CCS_HomMat_WCS, ROI_X_WCS, ROI_Y_WCS, ROI_Z_WCS, CCS_RectangleX, CCS_RectangleY, CCS_RectangleZ)
project_3d_point (CCS_RectangleX, CCS_RectangleY, CCS_RectangleZ, CamParam, RectangleRow, RectangleCol)
gen_region_polygon_filled (ROI, RectangleRow, RectangleCol)
smallest_rectangle2 (ROI, RowCenterROI, ColCenterROI, PhiROI, Length1ROI, Length2ROI)
* Create a measure
gen_measure_rectangle2 (RowCenterROI, ColCenterROI, PhiROI, Length1ROI, Length2ROI, 652, 494, 'bilinear', MeasureHandle)
measure_pairs (Image, MeasureHandle, 0.4, 5, 'all_strongest', 'all', RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, IntraDistance, InterDistance)
close_measure (MeasureHandle)
dev_display (Image)
disp_message (WindowHandle, 'Measuring the position of the pitch lines', 'window', 450, 25, 'red', 'false')
dev_set_color ('green')
RowPitchLine := (RowEdgeFirst+RowEdgeSecond)/2.0
ColPitchLine := (ColumnEdgeFirst+ColumnEdgeSecond)/2.0
disp_cross (WindowHandle, RowPitchLine, ColPitchLine, 6, 0)
image_points_to_world_plane (CamParam, FinalPose, RowPitchLine, ColPitchLine, 1, X1, Y1)
for i := 1 to |X1| by 1
    set_tposition (WindowHandle, RowEdgeFirst[i-1]+5, ColumnEdgeFirst[i-1]-20)
    if (i=|X1|)
        set_tposition (WindowHandle, RowEdgeFirst[i-1], ColumnEdgeFirst[i-2])
    endif
    write_string (WindowHandle, X1[i-1]$'.3f'+'mm')
endfor
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
dev_display (Image)
* Apply a line extraction and transform the resulting xld contours
* into the WCS
* Set the world coordinates of four points defining a ROI
ROI_X_WCS := [11,11,13,13]
ROI_Y_WCS := [4,6,6,4]
ROI_Z_WCS := [0,0,0,0]
* Transform the point coordinates into the image coordinate system
affine_trans_point_3d (CCS_HomMat_WCS, ROI_X_WCS, ROI_Y_WCS, ROI_Z_WCS, CCS_RectangleX, CCS_RectangleY, CCS_RectangleZ)
project_3d_point (CCS_RectangleX, CCS_RectangleY, CCS_RectangleZ, CamParam, RectangleRow, RectangleCol)
* Visualize the square in the original image
disp_polygon (WindowHandle, [RectangleRow,RectangleRow[0]], [RectangleCol,RectangleCol[0]])
dev_display (Image)
* create the ROI
gen_region_polygon_filled (ROI, RectangleRow, RectangleCol)
reduce_domain (Image, ROI, ImageReduced)
* Extract the lines
lines_gauss (ImageReduced, Lines, 1, 3, 8, 'dark', 'true', 'bar-shaped', 'true')
* Adapt the pose of the measurement plane to the tilted plane of the vernier
RelPose := [0,3.2,0,-14,0,0,0]
pose_to_hom_mat3d (FinalPose, HomMat3D)
pose_to_hom_mat3d (RelPose, HomMat3DRel)
hom_mat3d_compose (HomMat3D, HomMat3DRel, HomMat3DAdapted)
* Alternatively, the adaption can be done using the operators
* hom_mat3d_translate_local and hom_mat3d_rotate_local
* as shown in the following to lines
hom_mat3d_translate_local (HomMat3D, 0, 3.2, 0, HomMat3DTranslate)
hom_mat3d_rotate_local (HomMat3DTranslate, rad(-14), 'x', HomMat3DAdapted)
hom_mat3d_to_pose (HomMat3DAdapted, PoseAdapted)
* Transform the xld contour to the WCS using the adapted pose
contour_to_world_plane_xld (Lines, ContoursTrans, CamParam, PoseAdapted, 1)
get_contour_xld (ContoursTrans, YOfContour, XOfContour)
tuple_mean (XOfContour, MeterReading)
dev_display (Lines)
disp_message (WindowHandle, 'Meter reading: '+MeterReading$'.3f'+'mm', 'window', 400, 180, 'green', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
dev_close_inspect_ctrl (YOfContour)
dev_close_inspect_ctrl (XOfContour)
* Now, transform the whole image
WidthMappedImage := 652
HeightMappedImage := 494
dev_display (Image)
* First, determine the scale for the mapping
* (here, the scale is determined such that in the
  surroundings of the points P0 and P1,  the image scale of the
  mapped image is similar to the image scale of the original image)
distance_pp (X[0], Y[0], X[1], Y[1], DistP0P1WCS)
distance_pp (RCoord[0], CCoord[0], RCoord[1], CCoord[1], DistP0P1PCS)
Scale := DistP0P1WCS/DistP0P1PCS
* Then, determine the parameter settings for set_origin_pose such
* that the point given via get_mbutton will be in the center of the
* mapped image
dev_display (Image)
disp_message (WindowHandle, 'Define the center of the mapped image', 'window', 12, 12, 'red', 'false')
get_mbutton (WindowHandle, CenterRow, CenterColumn, Button1)
image_points_to_world_plane (CamParam, FinalPose, CenterRow, CenterColumn, 1, CenterX, CenterY)
set_origin_pose (FinalPose, CenterX-Scale*WidthMappedImage/2.0, CenterY-Scale*HeightMappedImage/2.0, 0, PoseNewOrigin)
gen_image_to_world_plane_map (Map, CamParam, PoseNewOrigin, 652, 494, WidthMappedImage, HeightMappedImage, Scale, 'bilinear')
map_image (Image, Map, ImageMapped)
dev_clear_window ()
dev_display (ImageMapped)
* In case, only one image has to be mapped, the operator
* image_to_world_plane can be used instead of the operators
* gen_image_to_world_plane_map together with map_image.
image_to_world_plane (Image, ImageMapped, CamParam, PoseNewOrigin, WidthMappedImage, HeightMappedImage, Scale, 'bilinear')

 

http://blog.sina.com.cn/s/blog_442bfe0e0100yfzo.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值