python+opencv实现基于图片序列的三维重建

三维重建一直是机器视觉研究的热门方向,比如,基于双目视觉,单目视觉,多视几何,光场三维重建等等。

每一种方法都有其有点和局限性。单目视觉需要拍摄多幅图像,并且在拍摄过程中需要不断的调整相机的聚焦位置,最后采取一定的融合方法来找到每幅图像中的清晰像素点,从而得到深度信息。这种方法也被称为焦点堆栈法。

在实际测试多个场景后,发现二级梯度评价函数和拉普拉斯评价函数融合效果较好。

程序实现如下:

import cv2
import numpy as np


def erjitidu(bh):#二级梯度评价函数
  qq=0.0
  m,n=bh.shape
  for i in range (2,m-1):
      for j in range (2,n-1):
        gx=(bh[i+1,j-1]+2*bh[i+1,j]+bh[i+1,j+1])-(bh[i-1,j-1]+2*bh[i-1,j]+bh[i-1,j+1])
        gy=(bh[i-1,j+1]+2*bh[i,j+1]+bh[i+1,j+1])-(bh[i-1,j-1]+2*bh[i,j-1]+bh[i+1,j-1])
        qq=qq+gx*gx+gy*gy
  return qq        


def laplas(x):#拉普拉斯评价函数
   qq=0.0
   m,n=x.shape
   for i in range (2,m-1):
       for j in range (2,n-1):
         qq=qq+(20*x[i,j]-4*x[i,j-1]-4*x[i,j+1]-4*x[i-1,j]-4*x[i+1,j]-x[i+1,j+1]-x[i+1,j-1]-x[i-1,j-1]-x[i-1,j+1]);
   return qq
def mean(img):
    qq=0.0
    m,n=img.shape
    for i in range (0,m):
        for j in range (0,m):
            qq=qq+img[i,j]
    return qq
    


def haxisuanfa(img1,img2): #哈希算法比较两幅图像的相似性
   tmp=cv2.resize(img1,(8,8),interpolation=cv2.INTER_CUBIC)
   tmp2=cv2.resize(img2,(8,8),interpolation=cv2.INTER_CUBIC)
   tmp=np.float32(tmp/4.0)
   tmp2=np.float32(tmp2/4.0)
   a,b=tmp.shape
   re=np.zeros((a,b))
   m=mean(tmp)
   n=mean(tmp2)
   me=m/64
   me2=n/64
   #print m,n,me,me2
   #print tmp
   for i in range (0,8):
      for j in range (0,8):
        if tmp[i,j]>me:tmp[i,j]=1
        else:tmp[i,j]=0       
         
        if tmp2[i,j]>me2:tmp2[i,j]=1         
        else:tmp2[i,j]=0        


        re[i,j]=tmp[i,j]-tmp2[i,j]
   
   num=0
   #print re
   for i in range (0,8):
      for j in range (0,8):
          if re[i,j]!=0:
            num=num+1
   #print num
   return num






lx=9.0
ly=9.0
pic=cv2.imread('img_1.jpg')
pic = cv2.cvtColor(pic, cv2.COLOR_BGR2GRAY)
m,n=pic.shape
m=int(m)
n=int(n)
depth=np.ones((m,n))


pinhole=cv2.imread('pinhole.tif')
pinhole = cv2.cvtColor(pinhole, cv2.COLOR_BGR2GRAY)
allfocus=pic


for num in range (2,32):
    print num
    name='img_'+str(num)+'.jpg'
    img=cv2.imread(name)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    for i in range (int(lx/2)+1,m-int(lx/2)-1,2):
        for j in range (int(ly/2)+1,n-int(ly/2)-1,2):
            aa=allfocus[i-int(lx/2):i+int(lx/2),j-int(ly/2):j+int(ly/2)]
            bb=img[i-int(lx/2):i+int(lx/2),j-int(ly/2):j+int(ly/2)]
            pin=pinhole[i-int(lx/2):i+int(lx/2),j-int(ly/2):j+int(ly/2)]
            pd_forward=erjitidu(aa)
            pd_next=erjitidu(bb)
            pd_f=laplas(aa)
            pd_n=laplas(bb)
            #pd_fh=haxisuanfa(aa,pin)
            #pd_nh=haxisuanfa(bb,pin)
            if pd_forward>pd_next or pd_f>pd_n:
                depth[i-int(lx/2):i+int(lx/2),j-int(ly/2):j+int(ly/2)]=depth[i-int(lx/2):i+int(lx/2),j-int(ly/2):j+int(ly/2)]
                allfocus[i-int(lx/2):i+int(lx/2),j-int(ly/2):j+int(ly/2)]=allfocus[i-int(lx/2):i+int(lx/2),j-int(ly/2):j+int(ly/2)]
            else:
                depth[i-int(lx/2):i+int(lx/2),j-int(ly/2):j+int(ly/2)]=num
                allfocus[i-int(lx/2):i+int(lx/2),j-int(ly/2):j+int(ly/2)]=img[i-int(lx/2):i+int(lx/2),j-int(ly/2):j+int(ly/2)]


cv2.imshow('allfocus',allfocus)
cv2.imshow('depth',depth)
cv2.waitKey(0)


你可能感兴趣的:(python学习)