Census作为立体匹配的代价函数之一,不论是局部立体匹配还是全局立体匹配都有很重要的作用,今天直入主题,直接给出代码并解释一下代码的实现,具体原理有很多优秀的博文已经贴出来了,本文不再赘述
import os
import time
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from numba import jit
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=104319258),如果还有不懂请私信我或给我留言
return census
'''上面那一部分是生成census变化后的图片,每一个像素坐标其实是一个2进制串,代表每一位的匹配情况
如果窗口大小选择为3,那么每一个像素匹配总数就是3*3=9次,但是要去掉中心点,也就是8次,8位2进制字符串能构成
的十进制数最大为255,当然也可以选择更大的窗口'''
'''下面这一部分是两张图片的匹配过程,因为最终目的是匹配左右图像,找出最佳视差'''
@jit
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'C:\Users\86198\Desktop\learn\AAAAAAAAAAAA相机程序\下载的双目图像')
limg=np.asanyarray(cv.imread('L.png',cv.IMREAD_GRAYSCALE),dtype=np.int64)
rimg=np.asanyarray(cv.imread('R.png',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)