本人是刚毕业的小菜鸡,最近工作上需要学习HALCON,在此记录一些学习过程,主要是算法流程、算子涉及的算法和常用的函数。如有错误恳请大佬们指正。
mosaic这一部分的例程主要是通过特征点匹配来实现对同一场景的图像块拼接,最后拼成一幅完整的图像。拼接后的图像一种是球形的(spherical),一种是三维立体的(cube)。
1.首先可以看到需要拼接的一共有72个小的图像块,格式为.jp2
2.构造应进行特征点匹配的图像块对的元组,一个图像与其相邻的图像和相隔6张的图像匹配,比如1和2、7,2和3、8匹配:
FF := [1,1,2,2,3,3,4,4,5,5,6]
TT := [2,7,3,8,4,9,5,10,6,11,12]
From := []
To := []
for J := 0 to 11 by 1
From := [From,(FF - 1 + 6 * J) % 72 + 1]
To := [To,(TT - 1 + 6 * J) % 72 + 1]
endfor
3.接下来分别计算图像的Forstner特征点,它包括角点特征点和区域特征点。points_foerstner(Image : : SigmaGrad, SigmaInt, SigmaPoints, ThreshInhom, ThreshShape, Smoothing, EliminateDoublets : RowJunctions, ColumnJunctions, CoRRJunctions, CoRCJunctions, CoCCJunctions, RowArea, ColumnArea, CoRRArea, CoRCArea, CoCCArea)。这个算子的参数看起来很复杂,我们一个一个的看,首先我们了解一下Foestner特征点的计算方法:
根据帮助文档,我们首先根据以下公式计算图像的非均匀和各向同性区域( the inhomogeneous, isotropic regions)
S为求导方式,包括'gauss','mean'。‘gauss’方式需要设定SigmaGrad和SigmaInt的值。
随后可以计算:
筛选出 inhomogeneity 和 isotropy 分别大于等于阈值ThreshInhom和ThreshShape 的点。
现在再看算子中的参数就比较清晰了,我们可以根据帮助文档来选择对应的值。
4.为了便于观察结果,将待匹配的图拼在一起,使用到了以下两个函数:concat_obj(将图放到元组中),tile_images_offset(将元组中的图拼接在一起),gen_cross_counter_xld(将点用十字小叉显示出来)
5.匹配特征点:
proj_match_points_ransac(Image1, Image2 : : Rows1, Cols1, Rows2, Cols2, GrayMatchMethod, MaskSize, RowMove, ColMove, RowTolerance, ColTolerance, Rotation, MatchThreshold, EstimationMethod, DistanceThreshold, RandSeed : HomMat2D, Points1, Points2)。该算子计算特征点之间的匹配度和两幅图像的齐次投影变换矩阵(homogeneous projective transformation matrix)。分为两个步骤,第一步根据窗口的灰度值来判断,方法有'ssd','sad','ncc'。为了提高算法性能,需要对匹配区域进行限制,因此需要设置RowMove, ColMove, RowTolerance, ColTolerance的值,此外,提供偏转角度的范围也可以提高计算精度,因此需要提供Rotation的值。在初步确出匹配点之后,使用RANSAC算法筛选出可能是误差的那些店,然后计算出投影矩阵HomMat2D,在这里需要设置DistanceThreshold,RandSeed的值,这里返回的points是特征点的编号。
6.这一个步骤是对固定相机进行自标定,使用到了stationary_camera_self_calibration( : : NumImages, ImageWidth, ImageHeight, ReferenceImage, MappingSource, MappingDest, HomMatrices2D, Rows1, Cols1, Rows2, Cols2, NumCorrespondences, EstimationMethod, CameraModel, FixedCameraParams : CameraMatrices, Kappa, RotationMatrices, X, Y, Z, Error)【这个帮助文档好长啊啊啊,具体原理下次用到的时候再研究吧,emmm】
stationary指没有发生移动,只有角度变换和缩放,projective是指相机是针孔相机,其模型可以用3D-2D投射模型进行描述,会用到的参数有图像个数、匹配点、投影矩阵、特征点个数、估计方法等,输出为相机的一些参数,然后我们继续往下看这些求解出的相机参数会用到哪些地方。
首先是移除径向畸变(radial distortion),一共分为以下四步:
cam_mat_to_cam_par (CameraMatrix, Kappa, 968, 648, CamParam)
change_radial_distortion_cam_par ('fixed', CamParam, 0, CamParOut)
gen_radial_distortion_map (Map, CamParam, CamParOut, 'bilinear')
map_image (Images, Map, Images)
为了将参考图像对齐到水平,进行了以下操作
hom_mat3d_identity (HomMat3D)
hom_mat3d_rotate (HomMat3D, rad(6), 'x', 0, 0, 0, HomMat3D)
RotMat := [HomMat3D[0:2],HomMat3D[4:6],HomMat3D[8:10]]
RotMats := []
for J := 0 to 71 by 1endfor
最后使用gen_spherical_mosaic和gen_cube_map_mosaic就可以产生相应的球形和立体图片了。第六个步骤只是简单地了解了一下,其中的理论知识今后要使用到的时候再继续学习~~下一篇学习如何使用harris角点来匹配和拼接图像