计算机视觉python--计算视差图

1. 立体视差

立体视差 ,亦称立体视像、立体知觉。基于双眼视差所 获得的深度知觉。

立体视差的测量包括三个步骤:
(1)必须从一幅图像中选出位于场景中一个表面上的某一特定位置;
(2)必须在另一幅图像中鉴别出同一个位置;
(3)测出这两个对应像点之间的视差。

在一组重复摄影的两张照片上(立体模式),同一地物的影象,沿着摄影基线(摄影地点和下一个摄影地点之间的飞行方向线)方向位置变换,这个变化量叫“立体视差”。

立体视差在每张照片上,从那点到照片基线(临接摄影地点与照片的摄影地点的像连结的直线),下垂线的足和主点(相片中心)之间叫距离之和。这是把相对两个照片的基线方向,使其成为一直线,按摄影顺序排列时,和相应的同一地物影象间的两个照片主点之间的间隔差。

2. 双目立体视觉

双目立体视觉(Binocular Stereo Vision是机器视觉的一种重要形式,它是基于视差原理并利用成像设备从不同的位置获取被测物体的两幅图像,通过计算图像对应点间的位置偏差,来获取物体三维几何信息的方法。

为什么双目相机才能得到深度?
下图从物理原理上展示了为什么单目相机不能测量深度值而双目可以的原因。我们看到红色线条上三个不同远近的黑色的点在下方相机上投影在同一个位置,因此单目相机无法分辨成的像到底是远的那个点还是近的那个点,但是它们在上方相机的投影却位于三个不同位置,因此通过两个相机的观察可以确定到底是哪一个点。
在这里插入图片描述

提到双目视觉就不得不提视差图:双目立体视觉融合两只眼睛获得的图像并观察它们之间的差别,使我们可以获得明显的深度感,建立特征间的对应关系,将同一空间物理点在不同图像中的映像点对应起来,这个差别,我们称作视差(Disparity)图像。
(对于视差的理解自己可以体验一下:将手指头放在离眼睛不同距离的位置,并轮换睁、闭左右眼,可以发现手指在不同距离的位置,视觉差也不同,且距离越近,视差越大。)

这里再解释一下视差:视差是指在两个摄像机图像之间的像素位置的差异。假设立体视觉相机中的左图像在位置(1,30)具有像素,并且相同的像素在右图像中的位置(4,30)存在,视差值或差值为(4-1)=3。视差值与深度成反比。

深度图:深度图像也叫距离影像,是指将从图像采集器到场景中各点的距离(深度)值作为像素值的图像。获取方法有:激光雷达深度成像法、计算机立体视觉成像、坐标测量机法、莫尔条纹法、结构光法。

点云:当一束激光照射到物体表面时,所反射的激光会携带方位、距离等信息。若将激光束按照某种轨迹进行扫描,便会边扫描边记录到反射的激光点信息,由于扫描极为精细,则能够得到大量的激光点,因而就可形成激光点云。

深度图与点云的区别: 深度图像经过坐标转换可以计算为点云数据;有规则及必要信息的点云数据可以反算为深度图像。 两者在一定条件下是可以相互转化的,之前的博客里,有使用PCL库实现过点云提取深度图,当然给出相机参数也是可以由深度图转为点云的。截图一个深度图:
在这里插入图片描述

3 归一化互相关(NCC)

在这里插入图片描述

4. 计算视差图的步骤

在这里插入图片描述

5 实验代码

import stereo
import scipy.misc
from PIL import Image
from pylab import *
from scipy.ndimage import *


def plane_sweep_ncc(im_l, im_r, start, steps, wid):
    # 使用归一化的互相关计算视差图像 """
    m, n = im_l.shape
    # 保存不同求和值的数组
    mean_l = zeros((m, n))
    mean_r = zeros((m, n))
    s = zeros((m, n))
    s_l = zeros((m, n))
    s_r = zeros((m, n))
    # 保存深度平面的数组
    dmaps = zeros((m, n, steps))
    # 计算图像块的平均值
    filters.uniform_filter(im_l, wid, mean_l)
    filters.uniform_filter(im_r, wid, mean_r)
    # 归一化图像
    norm_l = im_l - mean_l
    norm_r = im_r - mean_r
    # 尝试不同的视差
    for displ in range(steps):
        # 将左边图像移动到右边,计算加和
        filters.uniform_filter(roll(norm_l, -displ - start) * norm_r, wid, s)  # 和归一化
        filters.uniform_filter(roll(norm_l, -displ - start) * roll(norm_l, -displ - start), wid, s_l)
        filters.uniform_filter(norm_r * norm_r, wid, s_r)  # 和反归一化
        # 保存 ncc 的分数
        dmaps[:, :, displ] = s / sqrt(s_l * s_r)
    # 为每个像素选取最佳深度
    return argmax(dmaps, axis=2)


def plane_sweep_gauss(im_l, im_r, start, steps, wid):
    # 使用带有高斯加权周边的归一化互相关计算视差图像 """
    m, n = im_l.shape
    # 保存不同加和的数组
    mean_l = zeros((m, n))
    mean_r = zeros((m, n))
    s = zeros((m, n))
    s_l = zeros((m, n))
    s_r = zeros((m, n))
    # 保存深度平面的数组
    dmaps = zeros((m, n, steps))
    # 计算平均值
    filters.gaussian_filter(im_l, wid, 0, mean_l)
    filters.gaussian_filter(im_r, wid, 0, mean_r)
    # 归一化图像
    norm_l = im_l - mean_l
    norm_r = im_r - mean_r
    # 尝试不同的视差
    for displ in range(steps):
        # 将左边图像移动到右边,计算加和
        filters.gaussian_filter(roll(norm_l, -displ - start) * norm_r, wid, 0, s)  # 和归一化

        filters.gaussian_filter(roll(norm_l, -displ - start) * roll(norm_l, -displ - start), wid, 0, s_l)
        filters.gaussian_filter(norm_r * norm_r, wid, 0, s_r)  # 和反归一化
    # 保存 ncc 的分数
    dmaps[:, :, displ] = s / sqrt(s_l * s_r)
    # 为每个像素选取最佳深度
    return argmax(dmaps, axis=2)


im_l = array(Image.open('d:/picture/008/im2.ppm').convert('L'), 'f')
im_r = array(Image.open('d:/picture/008/im6.ppm').convert('L'), 'f')
# 开始偏移,并设置步长
steps = 50
start = 4

# ncc 的宽度
wid = 13

res = plane_sweep_ncc(im_l, im_r, start, steps, wid)

imsave('d:/picture/008/depyh6.jpg', res)

7 实验结果分析

原图
在这里插入图片描述
在这里插入图片描述

wid=3
在这里插入图片描述

wid=5
在这里插入图片描述

wid=7
在这里插入图片描述

wid=9
在这里插入图片描述

wid=11
在这里插入图片描述

wid=13

在这里插入图片描述

wid=20
在这里插入图片描述

wid=30在这里插入图片描述

wid=50
在这里插入图片描述

wid=100
在这里插入图片描述

窗口代价计算视差的原理
如果是以单个特征点来计算视差的话容易出现较大的误差,比如相似的特征点很多或者因视觉问题出现的看得见看不见问题,所以就要用视窗来计算视差,原理是通过一个特征点为中心点设定一个固定长度的正方形,然后计算视差的时候就是由这个正方形和另一张图片特征点所形成的正方形进行对比计算,计算时用合适的窗口匹配算法也就是ncc来计算,从而得出视差

结果分析
通过前面不同wid的值跑出来的结果图片对比得出,当wid的值偏小时也就是窗口略小时,会存在比较多的噪声,可能是因为虽然已经由特征点变成窗口但是由于窗口太小和其他的窗口相似的可能性还是很大,所以会存在噪声。我们可以看到再接下来的图片中可以看出,当wid以一个不大的数值增大,图片并没有出现太多的变化。然后我就想试一下,当窗口的宽度大到一定程度的时候的出来的结果会是什么样子的。就计算了wid=30,50,100的实验结果.我们可以发现图片变得越来越光滑导致与原图片所搭配出来的完美图片的差距越来越来,可以分析得出,当窗口越来越大时和小窗口相通,与他相似的特征点也会越来越多在步长不变的情况下,导致计算出来的视差没有明显的跨度,导致图片的颜色层次越来越少。

版权声明:本文为qq_41934490原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41934490/article/details/105774181

智能推荐

计算机视觉实验五 双目立体匹配获得视差图,深度图

完整源码链接 https://github.com/LamyaLi/cvLab 文章目录 一、 立体匹配的研究背景及意义 二、 立体匹配算法的基本实现思想 1、误差能量函数 2、基于最小平均误差能量的视差图 3、计算可靠度,生成具有可靠视差的视差图 4、由视差图生成深度图 三、 实现步骤与结果展示 1、计算误差能量,生成具有最小平均误差能量的视差图 2、计算可靠度,生成可靠视差的视差图 3、计算深...

计算机视觉---NCC视差匹配方法

文章目录 1. NCC原理 2. 运算流程 3. 实验内容 4.总结 1. NCC原理 NCC,normalization cross-correlation(归一化相关性),用于归一化待匹配目标之间的相关程度。 对于原始的图像内任意一个像素点(px,py)(px,py)(px,py)构建一个n×nn×nn×n 的邻域作为匹配窗口。然后对于目标相素位置(px+d...

计算机视觉——双目视觉匹配计算视差深度

源码地址:https://github.com/AOYLAOTANG/Computer-Vision/tree/main/stereo%E5%8F%8C%E7%9B%AE%E5%8C%B9%E9%85%8D 一、基本原理 Stereo双目立体匹配有很多算法, 比如SAD、BM、SGBM、GC,差别在于匹配时候的策略不同,我们这次要用到的NCC度量就是一种不错的方法。 其中I为目标图像,T为模板图像...

冒泡排序,及改进方式,性能优化400%>>>附图解加源码

首先源码附上,源码中带有注释,看不懂没关系,源码后面附带图解,最后附上代码效率提升图 源码如下: 方案一:其实实现很简单,两层循环,每次内层迭代出最大的一个值,将其放入数组最后一个位置,外层循环的末端便往前移一位。其原理如下图 方案一代码块: 方案二:优化改进 仔细观察上面的图,我们不难发现当迭代到图下这样的情况时,其实已经全排序好了,但是我们还是需要对它进行1,2,3,4,5,6的迭代,这些情况...

css3常用选择器

先介绍一下基本选择器,如下几种 *:通配符。选择页面的所有元素 E:元素选择器。对页面的一些元素进行选择,如p,div,li等 .class:类选择器 #id:id选择器。一个Id在一个页面中只能选择,这是和类选择器的区别 E F:后代选择器。如ul li。选中ul下的li E>F:子元素选择器。如下,可以用 h1 > strong {color:red;}使h1的子元素strong变...

猜你喜欢

python is not set from command line or npm configuration

问题 猜测原因  python版本冲突 解决方案  去官网找到最新版本python 点击下载,注意记住你下载的目录,下载好以后,打开这个目录下的文件夹,Python310, 整个文件夹复制一下 在项目里运行npm config list --json 找到python的路径   我的是 C:\\Python27\\python.exe 说明项目里用的还是py...

Java8 Stream流操作

前言 我们常常需要将一个容器转化成另一个容器,或是对这个容器中的数据进行批量处理,这时使用Stream流可以大大减少我们的工作量。 1 Stream概述 Java 8 是一个非常成功的版本,这个版本新增的Stream,配合同版本出现的 Lambda ,给我们操作集合(Collection)提供了极大的便利。 那么什么是Stream? Stream将要处理的元素集合看作一种流,在流的过程中,借助St...

带你玩转Visual Studio——带你跳出坑爹的Runtime Library坑

在Windows下进行C++的开发,不可避免的要与Windows的底层库进行交互,然而VS下的一项设置MT、MTd、MD和MDd却经常让人搞迷糊,相信不少人都被他坑过,特别是你工程使用了很多第三库的时候,及容易出现各种链接问题。看一下下面这个错误提示:  LIBCMT.lib(_file.obj) : error LNK2005: ___initstdio already defined...

git 设置 gitignore 忽略 __pycache__

清除git缓存中的pycache 直接删掉硬盘上的文件 如果我想保留硬盘上的这个文件,而只删除版本管理中的文件,就需要加入--cached参数。 切换分支出现问题 尽管我已经删除了__pycache__,硬盘也没有了,但是切换分支的时候依然是会提示本地重写的情况。 提示:需要我在切换分支之前,提交一次更新。 提交了更新之后,再来尝试切换分支,如下: 成功了,说明当做了任何变更之后,切换分支前需要执...

人生苦短,我用Python(二)— 爬取会议网站 EasyChair Smart CFP

寒假留校帮学长写了个爬虫,抓取会议网站上一些CFP信息。想着把一些知识点、坑点记下来,一来做个小总结给工作收收尾,二是以后再遇到好从容应对。 这是我写的第二个比较完善的爬虫了,比第一个要简单许多,完全过程化的代码,而且easychair这个网站页面布局比较友好,适合python新手、前端小白入门练习。但这个网站反爬比较厉害,写爬虫的过程中就被ban了好几次…… 制定抓取...