三维栅格地图构建之二:视差图及点云图

时间:2021-04-22 16:29:08

在上一步骤——双目校正的基础上可以很方便的获取视差图。视差即空间中同一点在左右目图像上的水平位置差。

自己凭感觉(不知道对错的)总结了一下,主要分为两大类:基于兴趣点的,不基于兴趣点的。

基于兴趣点的:需要先找到一幅图像中的特征点(也可以是两幅图像中的特征点,基于SIFT特征的匹配即是这种情况,不过对于特征并不唯一的特征点提取方法还是只找一幅图像中的特征点为好),再在另一幅图像中的同一及线上的一定范围内搜索,搜索相似的方法有很多,如:相关度,SAD,SSD等等。

不基于兴趣点的:假定一幅图像中的每一像素点都是兴趣点,再在另一幅图片中找对应像素点。

我的实验

前期:利用H.P Moravec的论文《Robot Spatial Perception by Stereoscopic Vision and 3D Evidence Grids》中的方法。一看就懂的,其中的Moravec兴趣算子是相当相当的古老了,只要把它稍改改就是harris算子。其实Moravec给出的代码中的Moravec算子实现很像Harris。以下是根据自己感觉上的理解编写的Moravec算子MATLAB代码。

function [out top]=HIns(img,rows,cols)


%[rows cols]=size(img);
Vp=zeros(rows,cols);
thosd1=100;
thosd2=800;  %高通滤波门限,可调
sqsize=7;  
%%%%%%%%%%%%%%%%%%% Moravec算子框移动过程
for i=fix(sqsize/2)+1:sqsize:rows-fix(sqsize/2)
    for j=fix(sqsize/2)+1:sqsize:cols-fix(sqsize/2)
        Vlu=0;Vl=0;Vld=0;Vu=0;Vd=0;Vru=0;Vr=0;Vrd=0;
        for x=-fix(sqsize/2):fix(sqsize/2)-1
            for y=-fix(sqsize/2):fix(sqsize/2)-1
             %Vlu=Vlu+(img(i+x,j+y)-img(i+x+1,j+y+1))^2;
       Vl=Vl+(img(i+x,j+y+1)-img(i+x,j+y))^2;
            %Vld=Vld+(img(i+x,j+y)-img(i+x+1,j+y-1))^2;
            % Vu=Vu+(img(i+x,j+y)-img(i+x-1,j+y))^2;
            % Vd=Vd+(img(i+x,j+y)-img(i+x+1,j+y))^2;
           % Vru=Vru+(img(i+x,j+y)-img(i+x-1,j+y+1))^2;
       Vr=Vr+(img(i+x,j+y+1)-img(i+x,j+y))^2;
            % Vrd=Vrd+(img(i+x,j+y)-img(i+x-1,j+y-1))^2;
            end
        end
         %Vp(i,j)=min([Vl,Vr]);%[Vlu,Vl,Vld,Vu,Vd,Vru,Vr,Vrd]);
         Vp(i,j)=Vl+Vr;
    end
end


out=zeros(rows,cols);
%%%%%%%%%%%%%%%%%%%%%%%高通滤波过程
top=0; %the max quantity for interest operator
for m=fix(sqsize/2)+sqsize+1:sqsize:rows-(fix(sqsize/2)+sqsize)-1
    for n=fix(sqsize/2)+sqsize+1:sqsize:cols-(fix(sqsize/2)+sqsize)-1
        ring=Vp(m+sqsize,n)+Vp(m+sqsize,n+sqsize)+Vp(m+sqsize,n-sqsize)+Vp(m-sqsize,n)+Vp(m-sqsize,n+sqsize)+Vp(m-sqsize,n-sqsize)+Vp(m,n+sqsize)+Vp(m,n-sqsize);
        out(m,n)=Vp(m,n)*8-ring;
        if out(m,n)>top
            top=out(m,n);
        end
    end
end
提取特征点后在另一幅图片中寻找对应的像素点。Moravec用的方法与SSD基本上相似。只是他在应用时利用小窗口内的像素和值作了预处理。并且应用相关公式计算匹配概率。这个不多说了,他的论文一看就懂(大师写的都通俗易懂)。下面是实验结果,上面图像时左图像,其上的黄点是Moravec垂直特征提取的结果;下面的是右图像,蓝色框是根据左图像中的特征点找到的对应匹配点(有很多误匹配,如果不嫌麻烦可以利用ransac进一步去除误匹配)。

三维栅格地图构建之二:视差图及点云图三维栅格地图构建之二:视差图及点云图

根据匹配结果,随便给一组摄像头参数,产生点云图如下:


三维栅格地图构建之二:视差图及点云图

后期:后期实验时更换了实验方法,主要原因是用以上方法产生的点云图太稀疏,没有足够的说服力,而若沿用以上方法一直做下去产生稠密的点云信息需要扩散,而扩散过程是很慢的,我无法忍受。

首先尝试的是“http://www.shawnlankton.com/2007/12/3d-vision-with-stereo-disparity/”中的方法,这是一种全局的匹配方法。作者将论文《Segment-Based Stereo Matching Using Belief Propogation and a Self-Adapting Dissimilarity Measure》中的方法反过来用了下,效果相当的好,相当有说服力。但要求视差必须足够小,且用一般摄像头拍出来的照片(可能是因为不清晰吧)处理效果相当不给力,放弃了。其生成的视差图如下:三维栅格地图构建之二:视差图及点云图


后来发现还是OpenCV的函数cvFindStereoCorrespondenceBM()比较给力啊。使用该函数需要注意设置好窗口大小,我的参数设置如下:

BMState->preFilterSize=43;

BMState->preFilterCap=43;

BMState->SADWindowSize=25;

BMState->minDisparity=0;

BMState->numberOfDisparities=32;

BMState->textureThreshold=10;

BMState->uniquenessRatio=20;

源图片对如下:

三维栅格地图构建之二:视差图及点云图

根据不同SAD窗口生成视差图如下:

三维栅格地图构建之二:视差图及点云图

选择(e)的设置,根据标定得到的摄像头参数,根据Q矩阵生成三维点云图。到三维坐标的转换过程实质如下公式,生成的点云图如下图:


  z=b*f/d;x=z*xr/f;y=z*yr/f。 

三维栅格地图构建之二:视差图及点云图


附上C与matlab下的常用匹配代码(基于区域的,来自G.D.Hager的讲义)

三维栅格地图构建之二:视差图及点云图三维栅格地图构建之二:视差图及点云图

设置不同的SAD窗口得到的视差图如下: 设置不同的SAD窗口得到的视差图如下: