图像的视差匹配(Stereo Matching)

这里要求用我们自己计算得到的视差图和给的视差图作比较来比较我们得到的视差图的好坏程度,我视差图返回的值是计算得到的视差乘以3之后的图,所以在计算时我不是两个值相差大于1,而是大于3,因为两个图像都乘3了,所以要大于3,我传入的参数是两个图像的矩阵,因为我是写了一个脚本咯跑所有测例的,在脚本里边已经把图像读出来了

<span style="font-size:18px;">function [percentnumberbadpixels] = PercentBadPixels(mydisparitymap,groundtruthdisparitymap)
mydisparitymap = double(mydisparitymap);
groundtruthdisparitymap = double(groundtruthdisparitymap);
[Rmydisparitymap, Cmydisparitymap] = size(mydisparitymap);
numbadpixels = 0;
for i = 1:Rmydisparitymap
    for j = 1:Cmydisparitymap
        if (abs(mydisparitymap(i,j) - groundtruthdisparitymap(i,j)) > 3)
              numbadpixels = numbadpixels+1;
        end
    end
end
percentnumbadpixels = numbadpixels/(Rmydisparitymap*Cmydisparitymap*1.0);
percentnumbadpixels = floor(percentnumbadpixels*100);
str = strcat(num2str(percentnumbadpixels),'%');
percentnumberbadpixels = str;
end
</span>

SSD:

左视差图

右视差图

实现细节:

输入的图像是24位的图像,但是这些计算都是基于强度(intensities)来计算的,在matlab中把彩色图转为灰度图的函数rgb2gray实质上就是转为其强度灰度图像。

原理:

如图:

对于同一图像,左眼看到的图像相对于右眼看到的图像的位置是不一样的,如上图,对于相同位置在右眼看到的图像的位置在左眼看到的图像的位置的前边,所以左视差图和右视差图的搜索方法不同,对于左视差图:

由于其位置比右眼看到的位置要远,则对于在右眼图像相同的物理位置应该往该位置的前边搜索才可能找到最相近的部分,即要减去d。

同理,对于右视差图则刚好相反,要加d。

实现细节:

1)首先把图像通过intensities转为灰度图像:

2)设定搜索深度d的值和patch的值,然后对图像进行补边界,使得可以从原图像的第一个像素开始进行匹配,我用的补边界的方法和以前做滤波时候原理一样,我都是补周围的值

3)对左图或右图中的每一个像素(i,j)作为patch的中心在另外的左图或右图上来寻找与之最相近的patch部分的搜索深度d,具体为:

对于模板图像中每个不移动的patch,把该patch里边的每一个像素和另外一张目标图对应得patch(加上搜索深度d的)上的像素点做差的平方和然后再累加起来,每一个d对应一个patch,每一个patch对应一个值(sum),然后把求出在搜索深度d的范围内最小的sum,从而得到该最小的sum的搜索深度d的值,当遇到边界时用判断来处理,具体实现如下:

如果是求右视差图的话,上边原理以及介绍了,要加上d来进行搜索

NCC

左视差图:

右视差图:

实现细节:

图像转为灰度图及边界处理和SSD相同,公式实现:

对左图或右图中的每一个像素(i,j)作为patch的中心,在另外的左图或右图上来寻找与之最相近的patch部分的搜索深度d。

1)对于模板图像中每个不移动的patch,把该patch里边的每一个像素和另外一张目标图对应的patch(加上搜索深度d的)上的对应像素点分别相乘相加,把模板图中的patch和目标图的patch中的像素值分别平方相加,然后再两个值相乘开方。

2) 每一个d对应一个patch,每一个patch对应一个值(ncctemp),然后把求出在搜索深度d的范围内最大的ncctemp,从而得到该最大的ncctemp的搜索深度d的值,当遇到边界时用判断来处理

NCC与SSD的区别:

NCC抗光照性强,SSD抗光照性弱

如:Add a small constant amount of intensity (e.g. 10) to all right eye images, and re-run the above two methods. Analyze how the intensity change affects
the results (i.e. the quality) of the two methods. Explain in which ways that NCC is a better matching cost than SSD.

这里我在view5加了常数10

NCC结果如下:Aloe disp1坏点率为24%

View5强度没有加10是坏点率为:24%

SSD 结果如下:Aloe disp1坏点率为38%

View5强度没有加10是坏点率为:26%

分析:

由上边公式可SSD是根据两幅图上patch里两个像素点差值的平方求和来找到最小的值,根据这个最小值我们认为距离为d的patch是匹配的部分,但是在拍照片是,会受到一些因素的影响,比如光照强度等,这样会照成左眼和右眼看到的图像的强度不一样,假如右眼看到的图像强度增加10,这样对于patch里边像素值相减得到的结果就会有很大的变化,从而造成求得的最小值的d也会不一样,因此的图像和右眼图像没有强度变化的结果有很大的不同。

而对于NCC来说,分子上是两个patch里边的像素分别相乘相加,而分母是每个patch里边的像素值平方然后求和在相乘开方,即使右眼的亮度加了,但是分子和分母的值都会同时增大,而且增大的值差不多相同,增大的值相除接近为1,所以得到的结果和右眼强度没有加10的结果基本上一样,没有多大的变化。

所以如果左眼图和右眼图受光照强度干扰比较大的情况下,NCC比SSD好。

nccdispl.m
function [output_img] = nccdispl(leftimg,rightimg)
[nrleft,ncleft,nleft] = size(leftimg);
[nrright,ncright,nright] =size(rightimg);
disparitymap = zeros(nrright,ncright);
if (nleft > 2)
   leftimg = rgb2gray(leftimg);
end
if (nright > 2)
    rightimg = rgb2gray(rightimg);
    rightimg = rightimg+10;
end
d = 70;
winsize = 11;
disparitymap = zeros(nrright,ncright);
leftimg = double(leftimg);
rightimg = double(rightimg);
leftimg = supplyborder(leftimg,winsize);
rightimg = supplyborder(rightimg,winsize);
win = (winsize-1)/2;
for i = 1+win:nrright+win
    for j = 1+win:ncright+win
        min = -9999999;
        for k = 0:d
            numerator = 0.0;
            powerrightwin = 0.0;
            powerleftwin = 0.0;
            for a=-win:win
                for b = -win:win
                    if j+b-k > 0
                        numerator = numerator+(leftimg(i+a,j+b)*rightimg(i+a,j+b-k));
                        powerleftwin = powerleftwin+(leftimg(i+a,j+b)*leftimg(i+a,j+b));
                        powerrightwin = powerrightwin+(rightimg(i+a,j+b-k)*rightimg(i+a,j+b-k));
                    end
                end
            end
            ncctemp = numerator/(sqrt(powerrightwin*powerleftwin));
            if (min < ncctemp && j+b-k > 0)
                min = ncctemp;
                recordk = k;
            end
        end
        disparitymap(i-win,j-win) = recordk;
    end
end
disparitymap = uint8(3*disparitymap);
output_img = disparitymap;
% imshow(disparitymap);
% imwrite(disparitymap,strcat('C:\Users\samsung-\Desktop\output\nccdisp1.png'));
end
</pre><pre name="code" class="plain"><pre name="code" class="plain" style="font-size:18px;">ssddispl.m

<pre name="code" class="plain">function [output_img] = ssddispl(leftimg,rightimg)
[nrleft,ncleft,nleft] = size(leftimg);
[nrright,ncright,nright] =size(rightimg);
if (nleft > 2)
   leftimg = rgb2gray(leftimg);
end

if (nright > 2)
    rightimg = rgb2gray(rightimg);
    rightimg = rightimg+10;
end
disparitymap = zeros(nrleft,ncleft);
d = 70;
winsize = 11;
leftimg = double(leftimg);
rightimg = double(rightimg);
leftimg = supplyborder(leftimg,winsize);
rightimg = supplyborder(rightimg,winsize);
win = (winsize-1)/2;
for i = 1+win:nrright+win
    for j = 1+win:ncright+win
        max = 99999999;
        for k = 0:d
            sum = 0.0;
            for a=-win:win
                for b = -win:win
                    if j+b-k > 0
                         temp = leftimg(i+a,j+b)-rightimg(i+a,j+b-k);
                         temp = temp*temp;
                         sum = sum+temp;
                    end
                end
            end
            if (max > sum && j+b-k > 0)
                max = sum;
                mind = k;
            end
        end
        disparitymap(i-win,j-win) = mind;
    end
end
disparitymap = uint8(3*disparitymap);
output_img = disparitymap;
% imshow(disparitymap);
% imwrite(disparitymap,strcat('C:\Users\samsung-\Desktop\output\ssddisp1.png'));
end

<pre name="code" class="plain">nccdispr.m

function [output_img] = nccdispr(leftimg,rightimg)
[nrleft,ncleft,nleft] = size(leftimg);
[nrright,ncright,nright] =size(rightimg);
if (nleft > 2)
   leftimg = rgb2gray(leftimg);
end
if (nright > 2)
    rightimg = rgb2gray(rightimg);
    rightimg = rightimg+10;
end
d = 70;
winsize = 11;
disparitymap = zeros(nrleft,ncleft);
leftimg = double(leftimg);
rightimg = double(rightimg);
leftimg = supplyborder(leftimg,winsize);
rightimg = supplyborder(rightimg,winsize);
win = (winsize-1)/2;
for i = 1+win:nrleft+win
    for j = 1+win:ncleft+win
        min = -999999;
        for k = 0:d
             numerator = 0.0;
             powerrightwin = 0.0;
             powerleftwin = 0.0;
            for a = -win:win
                for b = -win:win
                    if j+b+k <= ncleft+2*win
                        numerator = numerator+(rightimg(i+a,j+b)*leftimg(i+a,j+b+k));
                        powerrightwin = powerrightwin+(rightimg(i+a,j+b)*rightimg(i+a,j+b));
                        powerleftwin = powerleftwin+(leftimg(i+a,j+b+k)*leftimg(i+a,j+b+k));
                    end

                end
            end
            ncctemp = numerator/(sqrt(powerrightwin*powerleftwin));
            if (min < ncctemp && j+b+k <= ncleft+2*win)
                min = ncctemp;
                recordk = k;
            end
        end
        disparitymap(i-win,j-win) = recordk;
    end
end
disparitymap = uint8(3*disparitymap);
output_img = disparitymap;
% imshow(disparitymap);
% imwrite(disparitymap,strcat('C:\Users\samsung-\Desktop\output\nccdisp5.png'));
end
</pre><pre name="code" class="plain"><pre name="code" class="plain" style="font-size:18px;">ssddispr.m

<pre name="code" class="plain">function [output_img] = ssddispr(leftimg,rightimg)
[nrleft,ncleft,nleft] = size(leftimg);
[nrright,ncright,nright] =size(rightimg);
if (nleft > 2)
   leftimg = rgb2gray(leftimg);
end
if (nright > 2)
    rightimg = rgb2gray(rightimg);
    rightimg = rightimg+10;
end
disparitymap = zeros(nrleft,ncleft);
d = 70;
winsize = 11;
leftimg = double(leftimg);
rightimg = double(rightimg);
leftimg = supplyborder(leftimg,winsize);
rightimg = supplyborder(rightimg,winsize);
win = (winsize-1)/2;
for i = 1+win:nrleft+win
    for j = 1+win:ncleft+win
        max = 999999999;
        for k = 0:d
            sum = 0.0;
            for a=-win:win
                for b = -win:win
                    if j+b+k <= ncleft+2*win
                         temp = rightimg(i+a,j+b)-leftimg(i+a,j+b+k);
                         temp = temp*temp;
                         sum = sum+temp;
                    end
                end
            end
            if (max > sum && j+b+k <= ncleft+win)
                max = sum;
                mind = k;
            end
        end
        disparitymap(i-win,j-win) = mind;
    end
end
disparitymap = uint8(3*disparitymap);
output_img = disparitymap;
% imshow(disparitymap);
% imwrite(disparitymap,strcat('C:\Users\samsung-\Desktop\output\ssddisp5.png'));
end

				
时间: 2024-10-12 00:28:22

图像的视差匹配(Stereo Matching)的相关文章

基于MST的立体匹配及相关改进(A Non-Local Cost Aggregation Method for Stereo Matching)

怀着很纠结的心情来总结这篇论文,这主要是因为作者提虽然供了源代码,但是我并没有仔细去深究他的code,只是把他的算法加进了自己的项目.希望以后有时间能把MST这一结构自己编程实现!! 论文题目是基于非局部代价聚类(non-local cost aggregation)的立体匹配,从题目上看这篇论文不是局部算法,但是也不是传统意义上的全局算法.这要从基于窗结构局部立体匹配算法说起,如下图: 我们求左右两幅图像在视差d下一点的cost时,我们实际是求得以该点为中心半径为r的Windows内所有点的c

stereo matching

首先代码实现是根据"Segment-Based Stereo Matching Using Belief Propogation and Self-Adapting Dissimilarity Measure"来的,之所以使用这一论文主要是因为其http://vision.middlebury.edu/stereo/这网站上面排名较高,而且已经有人将其代码实现出来了(尽管代码与论文描述还是有些出入). 先附上代码链接(后续可能会对其改进):http://download.csdn.ne

《Segment-Tree based Cost Aggregation for Stereo Matching》读后感~

前段时间整理博客发现,自己关于立体匹配部分的介绍太少了,这可是自己花了一个季度研究的东西啊!读了自认为大量的文章,基本上有源码的都自己跑了一遍,还改进了多个算法.不写写会留下遗憾的,所以打算在立体匹配这一块多谢谢博客,一来用于分享,二来用于请教,三来用于备忘.本文介绍的文章就是CVPR2013的<Segment-Tree based Cost Aggregation for Stereo Matching>一文,介绍它原因有以下几点: 1.它是NLCA的变种. 2.它是CVPR的文章. 本文还

《A Non-Local Cost Aggregation Method for Stereo Matching》读后感~

最近一直在做stereo matching方向的研究,仔细研读了包括局部算法,全局算法,以及半全局算法三个方面的算法文献,对该方向有了比较清晰的了解,这次分享一下我对杨庆雄的经典文献<A Non-Local Cost Aggregation Method for Stereo Matching>(简称NL算法)的一些理解. 之所以想分享这篇文献,是因为文献明确抛弃了support window的算法思想,指出support window在视察估计上普遍具有陷入局部最优的缺陷,创新性的提出了基于

学习《Hardware-Ef?cient Bilateral Filtering for Stereo Matching》一文笔记。

本人一直用博客园的编辑器西博客,由于CSDN和博客园模板不一样,为了您阅读的方便,建议您通过博客园的博客阅读本文:http://www.cnblogs.com/Imageshop/p/3839879.html 个人收藏了很多香港大学.香港科技大学以及香港中文大学里专门搞图像研究一些博士的个人网站,一般会不定期的浏览他们的作品,最近在看杨庆雄的网点时,发现他又写了一篇双边滤波的文章,并且配有源代码,于是下载下来研读了一番,这里仅仅对一些过程做简单的记录,以防时间久了忘记. 关于杨庆雄的相关文章可见

opencv笔记(二十二)——模板匹配 template matching

模板匹配就是在给定一幅图像和一幅模板(一般模板比图像的尺寸小很多)的情况下,找到这个图像中最最相似于模板的位置,比如 第一幅是给定的图片,第二幅是模板,第三幅就是搜索到的匹配的位置. 这个搜索的过程,我没有在源码中求索,但是根据tutorial,应该是采用sliding window的方法,利用滑动的窗口,逐像素进行匹配.这个逐像素的意思,就是锚定某个像素之后,在这个像素的右边和下方,以template的宽度和高度的距离的范围内,进行模板与图像的相似度计算. 这种方法和行人检测中常用的方法类似.

稳定匹配 - Stable Matching

这篇文章将会对稳定匹配算法进行介绍及Python代码的实现,第一部分会针对稳定匹配的Gale-Shapley算法进行解析,第二部分就是用Python对该算法进行实现. 一.稳定匹配算法原理 1.1 介绍 稳定匹配(Stable Matching)问题就是假设现在有N个男生和N个女生跳舞选择伴侣,然后最开始的时候男.女生按照下面情况对彼此进行排序选择舞伴(见图1): 每个男生都对女生按照最喜欢到最不喜欢进行排序: 同样的,女生也是按照最喜欢的到最不喜欢对男生进行排序. 算法目标:每个男都找到唯一一

[Swift]LeetCode1023. 驼峰式匹配 | Camelcase Matching

A query word matches a given pattern if we can insert lowercase letters to the pattern word so that it equals the query. (We may insert each character at any position, and may insert 0 characters.) Given a list of queries, and a pattern, return an an

OpenCV2学习笔记(十三):利用SURF匹配不同图像的特征点

SURF算法是著名的尺度不变特征检测器SIFT(Scale-Invariant Features Transform)的高效变种,它为每个检测到的特征定义了位置和尺度,其中尺度的值可用于定义围绕特征点的窗口大小,使得每个特征点都与众不同.这里便是使用SURF算法提取两幅图像中的特征点描述子,并调用OpenCV中的函数进行匹配,最后输出一个可视化的结果,开发平台为Qt5.3.2+OpenCV2.4.9.以下给出图像匹配的实现步骤: 一.输入两幅图像,使用OpenCV中的cv::FeatureDet