密集匹配之动态规划DP

来源:互联网 发布:淘宝开店规则大全 编辑:程序博客网 时间:2024/05/17 07:46

       动态规划通常应用于最优化问题的求解中,Baker、Ohta 等将动态规划引入立体匹配中来获取视差图。动态规划匹配的过程可以分为两个阶段,建立视差空间和动态规划优化,将立体匹配问题转化为视差空间内寻找最优路径的问题。

       密集匹配通常会充分利用影像间的核线约束条件,对立体像对进行核线纠正,这样同名像点肯定位于对应的同名核线上,降低了匹配的难度。视差空间影像DSI(Disparity Space Image)是一种反映核线立体像对间同一扫描线视差关系的数据结构,将视差分析转化为一种类似的谱分析。其数学表达为:


其中w 为图像的宽度, NaN 表示在该视差值为d 时不可能有对应的同名点,L((* ))  是对应点之间的相似性测度函数。在匹配核线影像时,逐行计算像素的DSI,将每一行的DSI 依次叠加起来构成一个三维空间,称之为视差空间,视差空间包含了每个像素所有可能的视差取值。如下图所示,图中的x、y 代表图像的横纵坐标,d 表示视差搜索范围。


在建立好视差空间后,立体匹配问题就会转化为在视差空间内寻找最佳路径的问题,该路径上的视差累积的能量最小,相似性最大。一般采用从图像左边到右边的顺序,逐行进行。

实现过程如下:

//////minDeta、maxDeta为最小、大视差,P1、P2为平滑惩罚项void Dynamic(Mat lImg,Mat rImg,int minDeta,int maxDeta,int P1,int P2){if (lImg.empty() || rImg.empty() || (lImg.type() != CV_8UC3&&lImg.type() != CV_8UC1) || (rImg.type() != CV_8UC3&&rImg.type() != CV_8UC1)) return;Mat lGrayImg = lImg.type == CV_8UC3 ? cvtColor(lImg, lGrayImg, COLOR_BGR2GRAY) : lImg;Mat rGrayImg = rImg.type == CV_8UC3 ? cvtColor(rImg, rGrayImg, COLOR_BGR2GRAY) : rImg;int detaRang=maxDeta-minDeta+1;///视差范围Mat dispMap(lGrayImg.size(),CV_8UC1,Scalar::all(0));//////左视差图for(int r=0;r<lGrayImg.rows;r++){printf("动态规划...%d%%\r",(int)(r*100.0/(lGrayImg.rows)));/////方便查看进度Mat dif(Size(detaRang, lGrayImg.cols),CV_32FC1,Scalar::all(0));////视差空间Mat Emat(Size(detaRang, lGrayImg.cols),CV_32FC1,Scalar::all(0));/////能量空间Mat Dmat(Size(detaRang, lGrayImg.cols),CV_8UC1,Scalar::all(0));/////路径走向for(int c=0;c<lGrayImg.cols;c++){for(int d=0;d<detaRang;d++){int rc=c-d-minDeta;///当前视差下左像素对应对的右像素坐标if(rc>=0){dif.ptr<float>(c)[d] = SAD(lGrayImg, rGrayImg,Point2i(c, r),Point2i(c - d, r), 0);//////AD匹配代价}else{dif.ptr<float>(c)[d]=c<minDeta?0:dif.ptr<float>(c)[d-1];/////防止边界超限处代价对整体路径的影响}}}for(int c=1;c<lGrayImg.cols;c++){for(int match=0;match<detaRang;match++){float tmpmin=FLT_MAX;//////当前状态下路径代价int pmin=NULL;////路径走向for(int pre=0;pre<=detaRang;pre++){int Edata=dif.ptr<float>(c)[match];////数据项int dd=abs(match-pre);float Esmooth=dd>1?P2:(dd==0?0:P1);////视差等于1与大于1时候的平滑惩罚不同float E=Edata+Esmooth+Emat.ptr<float>(c-1)[pre];/////路径能量值if (E<tmpmin){tmpmin=E;pmin=pre;}}Emat.ptr<float>(c)[match]=tmpmin;Dmat.ptr<uchar>(c)[match]=pmin;}}int minID=0;float min=Emat.ptr<float>(lGrayImg.cols-1)[0];for(int i=0;i<detaRang;++i){if(Emat.ptr<float>(lGrayImg.cols-1)[i]<min){minID =i;min=Emat.ptr<float>(lGrayImg.cols-1)[i];}}//取得视差for(int c= lGrayImg.cols-1;c>=0;--c){int d=Dmat.ptr<uchar>(c)[minID];minID =d;dispMap.ptr<uchar>(r)[c]=d+minDeta;/////}}}

本人水平有限,如有错误,还望不吝指正,代码有一定删减,没有重新编译,如有错误,请自行调试,有问题请邮箱联系。

原创粉丝点击