Halcon图像拼接-算法速度优化

参考例程mosaicking_pyramid.hdev

原理简要说明:在上一篇的基础上,我们知道了在halcon中,图像拼接的大致原理,知道了算法运行的过程,其中一个关键步骤至关重要,那就是找角点。我们知道,在halcon中我们使用的harris算法来检测角点,这里涉及到一个问题,我们是全图遍历的方式来检测角点的,那么当一个图像过大时,相应的检测时间就要增加,再加上匹配,那总时间就是指数级的增长。

对于上述现象的解决办法,在halcon中的例程中也给出了方向,在讲解之前,我们先回忆一下,模板匹配中金字塔的作用,利用金字塔这个特性,可以让我们全图遍历的效率高出很多,即先在高层金字塔处找到匹配的点,因为在高层分辨率低,所以匹配速度不会慢,找到后,逐级递减往下,虽然分辨率越来越高,但是模板大致区域也被确定,那么我们就不用全图遍历了,只去遍历上一层确定的点即可;

对于检测角点这种需要全图遍历的活,我们也可以采用金字塔的特性,而halcon中也有这样的例子,大致原理就是,先在高等级的图像对中查找角点并进行匹配,那么这个时候会得到一个投影矩阵,将这个投影矩阵应用到下一级金字塔的图像对中,来限定查找范围(DistanceTolerance),这样就可以做到优化速度

1读取拍摄图像

跳过,详情见上篇,此处只对两张图像进行拼接

2定义图像对

跳过,详情见上篇,此处只对两张图像进行拼接

3算法流程

该例程中算法全部都在proj_match_points_ransac_guided这个函数中

1取图像的各个等级金字塔图像

ImageF,ImageT分别对应图像对的两张图像

gen_gauss_pyramid (ImageF, ImageFPyramid, 'constant', 0.5)

gen_gauss_pyramid (ImageT, ImageTPyramid, 'constant', 0.5)

2在循环中寻找角点做匹配,并且逐次递减金字塔等级

for Level := NumLevels to 1 by -1

*从高到低选择图像进行角点检测

* Select images from image pyramid

select_obj (ImageFPyramid, ImageFLevel, Level)

select_obj (ImageTPyramid, ImageTLevel, Level)

* Extract interest points in both images

*检测角点

points_harris (ImageFLevel, SigmaGrad, SigmaSmooth, Alpha, Threshold, RowsF, ColsF)

points_harris (ImageTLevel, SigmaGrad, SigmaSmooth, Alpha, Threshold, RowsT, ColsT)

* Calculate projection from point correspondences

*如果是第一次,也就是最上层的图像,那么使用默认的ransac算法来进行角点匹配

if (|HomMat2DGuide| == 0)

* On the highest pyramid level, use proj_mathc_points_ransac

get_image_size (ImageFLevel, Width, Height)

proj_match_points_ransac (ImageFLevel, ImageTLevel, RowsF, ColsF, RowsT, ColsT, 'ncc',\

10, 0, 0, Height, Width, [rad(-40),rad(40)], 0.5, 'gold_standard',\

2.5 * pow(2,4 - Level), 42, ProjMatrix, Points1, Points2)

else

*如果不是第一次,即有了上一等级图像的角点投影关系,利用ransac推导算法来进行角点匹配

*DistanceTolerance=10 * pow(2.0,4.0 - Level)是随着等级不断递减,图像分辨率越来越高的情况下,\

角点在高等级图像和低等级图像之间的容差值,不好理解就理解成角点的搜索窗口,太大就会找错,并且耗时

*DistanceThreshold=2.5 * pow(2.0,4.0 - Level)是投影变换矩阵预测的点与实际找到的角点之间的距离,在此距离内

*才会被认为是匹配的角点,太大就会找错

* On lower levels, use approximation from upper level as

* input for proj_match_points_ransac_guided

proj_match_points_ransac_guided (ImageFLevel, ImageTLevel, RowsF, ColsF, RowsT, \

ColsT, 'ncc', 10, HomMat2DGuide, 10 * pow(2.0,4.0 - Level),\

0.5, 'gold_standard', 2.5 * pow(2.0,4.0 - Level), 42, \

ProjMatrix, Points1, Points2)

endif

*在匹配的角点之间进行刚体变换

if (UseRigidTransformation)

* Use found point correspondences to calculate rigid transformation

* with vector_to_rigid

* Note, that the resulting transformation of proj_match_points_ransac_guided

* is ignored in this case.

RowF := subset(RowsF,Points1)

ColF := subset(ColsF,Points1)

RowT := subset(RowsT,Points2)

ColT := subset(ColsT,Points2)

vector_to_rigid (RowF + 0.5, ColF + 0.5, RowT + 0.5, ColT + 0.5, ProjMatrix)

ProjMatrix := [ProjMatrix,0,0,1]

endif

* To be used on the next lower pyramid level, the projection has

* to be adjusted to the new scale.

* 对于给下一级金字塔的图像的投影矩阵,Tx,Ty需要进行乘2(因为下一级图像放大了一倍),其他项不用

hom_mat2d_scale (ProjMatrix, 2, 2, 0, 0, HomMat2DGuide)

hom_mat2d_scale_local (HomMat2DGuide, 0.5, 0.5, HomMat2DGuide)

endfor

对于最后的两个矩阵缩放,原理如下

hom_mat2d_scale 是缩放矩阵中所有项

hom_mat2d_scale_local 是缩放除Tx©和Ty(f)的其他所有项

最后的这两句代码不一定这样写,只要达到缩放Tx©和Ty(f)的效果而其他不变的结果即可

4图像拼接

gen_projective_mosaic (Images, MosaicImage, 1, From, To, ProjMatrix, [2,1], 'false', MosaicMatrices2D)

5结果演示

可以看到,在以不同等级的金字塔图像开始后,角点匹配的速度被优化了

从原来的原图像(1级金字塔)匹配需要2.42s,到4级金字塔只需要0.0773s,当然,不是金字塔越高越好,根据图像分辨率和角点分布来确定,例程中生成了9层,但是在进行匹配的时候只用到了1~4层,因为后面的图像太过模糊,进行匹配没意义

制作不易,觉得帮到了您,还请点个赞

另外,若觉得本文写的与您理解的有些出入,欢迎交流

Copyright © 2088 一键全脑游戏活动站 - 脑力挑战专属福利 All Rights Reserved.
友情链接