Census立体匹配算法算法的Python实现

1.前言

Census作为立体匹配的代价函数之一,不论是局部立体匹配还是全局立体匹配都有很重要的作用,今天直入主题,直接给出代码并解释一下代码的实现,具体原理有很多优秀的博文已经贴出来了,本文不再赘述

2.实现

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)


成果

在这里插入图片描述
图一:运行速度有待提升,目前任务为作出demo,等各类立体匹配算法全部完成后会进行代码的优化

Census立体匹配算法算法的Python实现_第1张图片
图二:census变换后的左图
Census立体匹配算法算法的Python实现_第2张图片
图三:最终生成的深度图

你可能感兴趣的:(计算机视觉,二进制,机器视觉)