映射校正效果如下:
几个核心算子说明如下:
gen_image_to_world_plane_map( : Map : CameraParam, WorldPose, WidthIn, HeightIn, WidthMapped, HeightMapped, Scale, MapType : )
/************************************************************************
* @生成带矫正映射信息的图像
* @param Map [OUT] 输出的映射图
* @param CameraParam [IN] 相机内参
* @param WorldPose [IN] 世界坐标系在摄像机坐标系中的3D位姿
* @param WidthIn [IN] 要转换的图像的宽
* @param HeightIn [IN] 要转换的图像的高
* @param WidthMapped [IN] 映射图的宽
* @param HeightMapped [IN] 映射图的高
* @param Scale [IN] 坐标系的单位尺寸
* @param MapType[IN] 映射的算法类型
************************************************************************/
map_image(Image, Map : ImageMapped : : )
/************************************************************************
* @brief 映射图像
* @param Image [IN] 原始图
* @param Map [IN] 映射图
* @param ImageMapped [OUT] 映射后的图像
************************************************************************/
image_points_to_world_plane( : : CameraParam, WorldPose, Rows, Cols, Scale : X, Y)
/************************************************************************
* @brief 将像素坐标转换到世界坐标系中(z=0)
* @param cameraParam [IN] 相机内参
* @param worldPose [IN] 世界坐标系在摄像机坐标系中的3D位姿
* @param Rows [IN] 要转换的点的行坐标
* @param Cols [IN] 要转换的点的列坐标
* @param scale [IN] 坐标系的单位尺寸
* @param x [OUT] 在世界坐标系中的点的X坐标
* @param y [OUT] 在世界坐标系中的点的Y坐标
************************************************************************/
camera_calibration( : : NX, NY, NZ, NRow, NCol, StartCamParam, NStartPose, EstimateParams : CameraParam, NFinalPose, Errors)
/************************************************************************
@brief 标定相机,确定相机的内参和外参
* @param NX [IN] 标志点x坐标的有序元组(单位m)
* @param NY [IN] 标志点y坐标的有序元组(单位m)
* @param NZ [IN] 标志点z坐标的有序元组(单位m)
* @param NRow [IN] 提取到的标志点的行坐标(单位像素)
* @param NCol [IN] 提取到的标志点的列坐标(单位像素)
* @param StartCamParam [IN] 相机内参初始值
* @param NStartPose [IN] 相机外参初始值
* @param EstimateParams [IN] 需要预估的相机参数
* @param CameraParam [OUT] 相机内参
* @param NFinalPose [OUT] 相机外参
* @param Errors [OUT] 平均误差距离(像素)
************************************************************************/
源代码已经做详细注释
*关闭窗口 dev_close_window () dev_close_window () *打开指定大小、颜色背景的窗口 dev_open_window (0, 0, 768/2, 576/2, 'black', WindowHandle1) dev_update_pc ('off') dev_update_window ('off') dev_update_var ('off') dev_update_time ('off') dev_set_draw ('margin') dev_set_line_width (3) * * Calibrate the camera.(标定相机)步骤一 * * 标定板描述文件 CaltabName := 'caltab_big.descr' * make sure that the file 'CaltabDescrName' is in the current directory, * the HALCONROOT/calib directory, or use an absolut path *初始相机参数:焦距、畸变系数Kappa,Sx,Sy,Cx,Cy,ImageWidth,ImageHeight StartCamPar := [0.008,0,0.0000086,0.0000086,384,288,768,576] *物体在空间坐标系中的位姿数组 NStartPose := [] *行角点数组 NRow := [] *列角点数组 NCol := [] *X、Y、Z从标定表文件获取计算值 caltab_points (CaltabName, X, Y, Z) *创建空的图像元组 gen_empty_obj (Images) *图像的数目 NumImages := 10 *接下来for循环,依次读取、处理NumImages张图像 for I := 1 to NumImages by 1 *读取图像:Image得到图像数据 read_image (Image, 'calib/calib-3d-coord-'+I$'02d') *将单个Image加入元组Images中 concat_obj (Images, Image, Images) *显示Image dev_display (Image) *在图像中找到标定板的区域:图像,标定板描述文件,滤波核大小,二值化值 find_caltab (Image, Caltab, CaltabName, 3, 112, 5) *设置区域颜色:绿色 dev_set_color ('green') *显示图像中标定板的区域 dev_display (Caltab) *(核心函数:搜寻图像的原始点)在图像中找到标定板的各个角点坐标和初始位姿 find_marks_and_pose(Image, Caltab, CaltabName, StartCamPar, 128, 10, 18, 0.9, 15, 100, RCoord, CCoord, StartPose) *设置颜色:红色 dev_set_color ('red') *在窗口上圆形标记角点的位置 disp_circle (WindowHandle1, RCoord, CCoord, gen_tuple_const(|RCoord|,1.5)) *一个图像位姿加入位姿元组 NStartPose := [NStartPose,StartPose] *所有图像角点行坐标数组相连 NRow := [NRow,RCoord] *所有图像角点列坐标数组相连 NCol := [NCol,CCoord] endfor dev_update_time ('on') disp_continue_message (WindowHandle1, 'black', 'true') stop () * * Calculate the mapping.(计算带矫正信息的图像)步骤二 * *(核心函数)标定相机参数,对步骤一的数据进行计算处理 camera_calibration (X, Y, Z, NRow, NCol, StartCamPar, NStartPose, 'all', CamParam, NFinalPose, Errors) *生成空的对象:包含矫正映射信息的图像 gen_empty_obj (Maps) *for循环一次处理一组对应的图像 for NumImage := 1 to NumImages by 1 * Obtain the pose of the calibration table. *获取标定出来的位姿3D Pose := NFinalPose[(NumImage-1)*7:(NumImage-1)*7+6] *设置新的原始3D位姿 set_origin_pose (Pose, -1.125, -1.0, 0, PoseNewOrigin) *(核心函数)生成带矫正映射信息的图像MapSingle gen_image_to_world_plane_map (MapSingle, CamParam, PoseNewOrigin, 768, 576, 900, 800, 0.0025, 'bilinear') *将单张图像加入图像元组Maps concat_obj (Maps, MapSingle, Maps) endfor disp_continue_message (WindowHandle1, 'black', 'true') stop () *代码到此处:有了NumImages张标定的原图 + NumImages张带矫正映射信息的图像, *接下来While循环,一张一张的矫正图像 * * Map the images.(矫正图像)步骤三 * *窗口设置 dev_open_window (0, 391, 900/2, 800/2, 'black', WindowHandle2) Button := 0 NumImage := 1 while (Button # 1) dev_set_window (WindowHandle1) dev_set_part (0, 0, 575, 767) dev_clear_window () *从图像元组中选择一张图像 select_obj (Images, Image, NumImage) *显示选择的图像 dev_display (Image) disp_message (WindowHandle1, 'Press any mouse button to stop', 'image', -1, -1, 'black', 'true') *选择对应位置的带矫正信息的图像 select_obj (Maps, MapSingle, NumImage) *(核心函数)矫正图像:原图,带矫正信息图,矫正结果图 map_image (Image, MapSingle, ImageMapped) *以下为窗口、循环之类的处理,与图像处理没什么关系 dev_set_window (WindowHandle2) dev_set_part (0, 0, 799, 899) dev_clear_window () dev_display (ImageMapped) NumImage := NumImage + 1 if (NumImage > NumImages) NumImage := 1 endif dev_error_var (Error, 1) dev_set_check ('~give_error') get_mposition (WindowHandle1, R, C, Button) dev_error_var (Error, 0) dev_set_check ('give_error') if (Error#H_MSG_TRUE) Button := 0 endif if (Button) break endif stop() endwhile dev_set_window (WindowHandle2) dev_close_window ()
另一篇贴子也是讲解这个例子,可以对照一下:

