census介绍与python实现

census介绍与python实现立体匹配之 Census Transform 1 立体匹配算法主要可分为两 大类 基于局部约束和基于全局约束的立体匹配算法 一 基于全局约束的立体匹配算法 在本质上属于优化算法 它是将立体匹配问题转化为寻找全局能量函数的最优化问题 其代表算法主要有图割算法

大家好,我是讯享网,很高兴认识大家。

立体匹配之Census Transform

1、立体匹配算法主要可分为大类:基于局部约束和基于全局约束的立体匹配算法.

(一)基于全局约束的立体匹配算法:在本质上属于优化算法,它是将立体匹配问题转化为寻找全局能量函数的最优化问题,其代表算法主要有图割算法、置信度传播算法和协同优化算法等.全局算法能够获得较低的总误匹配率,但算法复杂度较高,很难满足实时的需求,不利于在实际工程中使用.

(二)基于局部约束的立体匹配算法:主要是利用匹配点周围的局部信息进行计算,由于其涉及到的信息量较少,匹配时间较短,因此受到了广泛关注,其代表算法主要有 SAD、SSD、NCC等。

2、本文采用局部约束的立体匹配算法

(1)Census 变换

Census 变换在实际场景中,造成亮度差异的原因有很多,如由于左右摄像机不同的视角接受到的光强不一致,摄像机增益、电平可能存在差异,以及图像采集不同通道的噪声不同等,cencus方法保留了窗口中像素的位置特征,并且对亮度偏差较为鲁棒,简单讲就是能够减少光照差异引起的误匹配。

实现原理:在视图中选取任一点,以该点为中心划出一个例如3 × 3 的矩形,矩形中除中心点之外的每一点都与中心点进行比较,灰度值小于中心点即记为1,灰度大于中心点的则记为0,以所得长度为 8 的只有 0 和 1 的序列作为该中心点的 census 序列,即中心像素的灰度值被census 序列替换。经过census变换后的图像使用汉明距离计算相似度,所谓图像匹配就是在视差图中找出与参考像素点相似度最高的点,而汉明距正是视差图像素与参考像素相似度的度量。具体而言,对于欲求取视差的左右视图,要比较两个视图中两点的相似度,可将此两点的census值逐位进行异或运算,然后计算结果为1 的个数,记为此两点之间的汉明值,汉明值是两点间相似度的一种体现,汉明值愈小,两点相似度愈大实现算法时先异或再统计1的个数即可,汉明距越小即相似度越高。(尽管census变换提高了匹配鲁棒性,但其包含的图像信息有限,原始灰度信息己经完全被抛弃了,因此不能将变换结果用于单像素或较小窗口的匹配,仍需要使用与其他区域匹配方法中类似的匹配窗口)变换过程如图 1 所示。

127  126 130                1    1    0

126  128 129      --->    1    *    0         ---> cencus序列 {}

127  131  111               1    0    1                                         

                                                                                               --->  异或 {0} --->汉明距为4


讯享网

110  126 101              1    0    1

146  120 127      --->  0    *    0          ---> cencus序列  {}

112  101  111             1    1    1

                                           图 1

 用FPGA实现时,思路就是先用RAM或者shift register 实现矩阵,然后捕捉相关点进行比较、异或等操作

python实现

配置环境:anaconda+opencv+python(对配置有疑问的可以下面评论,我出一篇具体配置方法)

python代码

import os import time import cv2 as cv import numpy as np import matplotlib.pyplot as plt from numba import jit lres=census(limg[:,maxDisparity:w]) maxDisparity=12 #最大视差,也就是搜索范围,搜索范围越大耗时越长 window_size=5#滑动窗口大小,窗口越大匹配成功难度越高 same=np.int64(window_size/2)#窗口大小的一半向下取整,比如用来衡量窗口左上角与窗口中点的距离的x与y坐标 @jit def census (img): size=np.shape(img)[0:2] h=size[0] w=size[1] census = np.zeros((h-2*same, w-2*same), dtype=np.int64) #census就是经过变换后的图像 cp = img[same:h-same, same:w-same] #cp是变换中心点的坐标,0,0点作为左上角的窗口中,中心点就是(same,same) offsets = [(u, v) for v in range(window_size) for u in range(window_size) if not u == same == v] #offset是分别衡量某个点作为窗口左上角是否匹配成功,作为窗口左上角向左平移一个匹配是否成功,一直到作为窗口右下角匹配是否成功,都有衡量 for u,v in offsets: census = (census << 1) | (img[v:v+h-2*same, u:u+w-2*same] >= cp)#这里是最为难懂的,请参考一下[我的另一篇博文](https://editor.csdn.net/md/?articleId=),如果还有不懂请私信我或给我留言 return census def hanming(limg,rimg,dispmap,Diffmap): size=np.shape(limg)[0:2] h=size[0] w=size[1] lres=census(limg[:,maxDisparity:w]) rres=census(rimg[:,0:w-maxDisparity]) for x in range(0,np.shape(lres)[0]): for y in range(maxDisparity,np.shape(lres)[1]): for i in range(0,maxDisparity): dispmap[x,y,i]='{:025b}'.format(((rres[x,y-i]) ^ (lres[x,y]))).count('0')#从当前位置开始,在右图中寻找和左图最接近的二进制串,从而完成匹配 for x in range(0,np.shape(lres)[0]): for y in range(0,np.shape(lres)[1]): val=np.sort( dispmap[x,y,:])#排名 val_id=np.argsort(dispmap[x,y,:])#找出最接近的 Diffmap[x,y]=dispmap[x,y,:].argsort()[-1] #os.chdir(r'') limg=np.asanyarray(cv.imread('4.jpg',cv.IMREAD_GRAYSCALE),dtype=np.int64) rimg=np.asanyarray(cv.imread('4.jpg',cv.IMREAD_GRAYSCALE),dtype=np.int64) # img_size=np.shape(limg) size=np.shape(limg)[0:2] h=size[0] w=size[1] rres=np.zeros((np.shape(lres)[0],np.shape(lres)[1],maxDisparity),dtype=np.int64) dispmap=np.zeros((np.shape(lres)[0],np.shape(lres)[1],maxDisparity),dtype=np.int64) Diffmap=np.zeros((np.shape(lres)[0],np.shape(lres)[1]),dtype=np.int64) tic1=time.time() hanming(limg,rimg,dispmap,Diffmap) plt.imshow( Diffmap[:,maxDisparity:]) plt.show() print('用时:',time.time()-tic1)

讯享网

实现结果图

 

小讯
上一篇 2025-02-26 17:48
下一篇 2025-02-13 21:54

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/45239.html