通过cv2输出左右眼视差图, 然后根据视差图输出深度边沿

视差图是神经网络里的x--feature,分左右眼

 通过cv2输出左右眼视差图, 然后根据视差图输出深度边沿_第1张图片

 通过cv2输出左右眼视差图, 然后根据视差图输出深度边沿_第2张图片

计算过程是先将左眼(或右眼)图片作为主视图(基准),然后用另外一眼图片缓慢的水平划过主视图,

这时候会有部分区域重合,相当于人看东西的时候双目同时注视.

记住这个水平移动的距离就可以计算出景深.计算公式还包含焦距,双眼距离.

小技巧,为了提高计算速度,可以将彩色图片转化为灰度图,如下.

通过cv2输出左右眼视差图, 然后根据视差图输出深度边沿_第3张图片

小技巧,为了提高计算速度,可以将多张滑动重合图堆叠在一起,构成一张3D矩阵图,这里将3D矩阵图做个2D切片:

然后从层,行,列3个维度中,选取行的维度进行切片,再卷积,最后得到重合位置,这里做个2D切片:

用到的卷积核见程序中的 ---kernel.  卷积核还有继续改进的空间.

注意图片上边沿附近的2个小白点:

将多个重合位置重新降维到2D得到结果. 这样就得到了深度图, 可以作为 神经网络里的y--label, 可惜简单的算法只能 边沿涂色,需要后续处理才能将整个物体涂色.

 通过cv2输出左右眼视差图, 然后根据视差图输出深度边沿_第4张图片

# 改成 320 x 240 分辨率

# 用 卷积去除彩虹, 卷积核的作用是时间轴上的边界重叠位置,计算重合时刻的视差,

# todo  现在是边界有深度信息,面没有深度信息, 计算的结果仅仅是边沿, todo 将视差向右传播,方法是??(直到另外一个极值?)


# todo 滑动距离需要改变





''' 伪代码:

frame2 [0:240,  0:320]                              左右眼照片,320x240

cv2.cvtColor(imgL,cv2.COLOR_BGR2GRAY)              灰度化

cv2.addWeighted()                                  融合左右眼算法,

                                                  #  将shift=1  shift=200 堆叠成3D 阵列

                                                  #  将3D 转换为2D,选择极值,并记录层数 



                                                  #  将2D转换为深度图,

                                                  #  将深度图转换为色彩图

'''

##############      

import cv2
import numpy as np
import time

start = time.time()

dx, dy = 0, -1                                                            # 左眼图片滑动的dx  向右偏移量,  dy=-1  制造偏差修正,固定的偏移量
  #  dx=-3 窗外的塔吊重合
  #  dx=-5 办公室远处的绿植重合
  #  dx=-99 距离摄像头15cm的鼻子重合



DATA3D  =np.zeros((30,240,320), dtype=np.uint8)                              # 存储             # 2图相减的值,堆叠DATA3D。         每个单元格里是:左右眼差异            所有的视差融合图  高 x 宽 x 视差(像素),   --一开始申请连续空间,数据搬运工作量少,比较节约cpu时间,  
DATA3D2 =np.zeros((30,240,320), dtype=np.uint8)                            # 存储            视差融合点 

DATA2D=np.zeros((240,320), dtype=np.uint8 )                                    # 存储            高 x 宽 ,每个单元格里是:  融合后最小值的视差(像素)
# print(DATA3D.shape)

keyInput=0


########################################################################### 

kernel = np.array((                                             #  卷积核,用于查找左右眼重合点
        [-1, -1,  1,  1,  0],
        [-1, -1,  1,  0, -1],
        [-1, -1,  0, -1, -1],
        [-1,  0,  1, -1, -1],
        [ 0,  1,  1, -1, -1]),
        dtype="float32") / 1

##############   获取图片 ############################


for k in range(0, 1 ):  
    print("读取左右眼图片   -------------")
    imgL =cv2.imread("imgL00009.png")                                                            #读取 图片L ,图片R
    imgR =cv2.imread("imgR00009.png") 
#########################################################

    imgL_gray=cv2.cvtColor(imgL,cv2.COLOR_BGR2GRAY)                        #将彩色图片L转换至灰度图片
    ##  rows, cols, ch = imgL.shape                                                                        # for 彩色图片
    rows, cols    = imgL_gray.shape
    ## imgL_gray=imgL_gray.astype(np.int16)

    imgR_gray=cv2.cvtColor(imgR,cv2.COLOR_BGR2GRAY)                         #将彩色图片R转换至灰度图片
    cv2.imshow('imgR_gray',imgR_gray)
    
###########################################################################################   滑动 + 堆叠   

    for i in range(2,31):                                                                                              # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  todo 滑动距离需要改变
        print("视差图相减,再堆叠-------------------",i)
        MAT = np.float32([[1, 0, -2*i], [0, 1, dy]])                                                                                  # 构造平移变换矩阵 ,[dx, dy]像素移动 
        imgL_gray_shift = cv2.warpAffine(imgL_gray, MAT, (cols, rows))                                # 仿射变换,移动图片。默认为黑色填充
        # imgL_gray_shift = cv2.warpAffine(imgL_gray, MAT, (cols, rows), borderValue=(255,255,255))   # 白色填充

        imgMerge=cv2.absdiff(imgR_gray ,   imgL_gray_shift )               # 2图相减的值,   

        '''                                                                                                                           # <<<<<<< debug  注释符号' ' ' 需要对齐
        ## 将 imgMorphClose0    imgMorphClose1  做与运算

        # imgMerge= cv2.bitwise_xor(imgR_Threshold ,imgL_Threshold)   ## 做与或运算   xor
        # imgMerge= cv2.bitwise_and(imgR_Threshold ,imgL_Threshold)   ## 做与运算     and
        # imgMerge= cv2.bitwise_or(imgR_Threshold ,imgL_Threshold)      ## 做或运算     or
        
        # imgMerge= cv2.add(imgR_Threshold ,imgL_Threshold)           ## 做加运算     add,效果等同于 or
        # imgMerge= cv2.bitwise_not(imgR_Threshold)   ## 做非运算     not
        '''
        DATA3D[i-2,:,:] = imgMerge                                                                    # 2图相减的值,--------------------------------------------堆叠DATA3D。 

###########################################################################################    卷积 + 堆叠 

    for i in range(0,240):
        probe2D= DATA3D[:, i, :]                                                                                                               # 切片 -------------- 切片DATA3D, 方向在 层,行,列  的 行维度
        imgProbe2DMin = cv2.filter2D(probe2D, -1, kernel)                                                       #  卷积  求重合点-------------- cv.filter2D(源图像,输出数据类型  ,卷积核)   , 输出数据类型 =-1 表示输出类型和输入相同 
        DATA3D2[:,i,:] = imgProbe2DMin                                                                                             #  堆叠 --------------堆叠DATA3D2,  方向同上 

    ############################################  #   显示 3D矩阵的剖面    
    imgTemp = DATA3D[:,200,:] *90                                              ##   未经卷积处理过的3D矩阵的剖面, *90 表示增强信号,否则看不到
    cv2.imshow( 'imgTemp', imgTemp  )

    imgTemp1 = DATA3D2[:,200,:] *90                                          ##   已经卷积处理过的3D矩阵的剖面, *90 表示增强信号,否则看不到
    cv2.imshow( 'imgTemp1', imgTemp1  )


   ########################### # 求极值

    DATA2D  = np.argmax( DATA3D2,axis = 0 ).astype(np.uint8) * 9                                    # np.argmin( ) 返回了最小值的位置 
                                                                                                                                                                      # debug   <<<<<<<<<<<<<<<<<<<程序会将uint8 自动更改为 int64
        # print(DATA2D.dtype)                         
        # print( DATA2D.shape )                     

    outPutColor = cv2.applyColorMap(DATA2D, cv2.COLORMAP_JET)                      # COLORMAP_JET = 2, 蓝到红
                                                                                # COLORMAP_RAINBOW = 4,红到蓝

    cv2.imshow( 'outPutColor',  outPutColor  )                         # 如果 DATA2D 声明的时候没有指定数据类型,或者在计算过程中数据类型改变,可以在这里指定为 uint8


#########  键盘响应 ,兼计时器  ########################################3 
    keyInput       = cv2.waitKey( 0)   & 0xFF                                #等待键盘输入,间隔  xx us                         #  debu g <<<<<<<<<<<<<<< 设置 waitKey(0) , 则表示程序会无限制的等待用户的按键事件
    if (keyInput == ord('q')) | (keyInput == 27 ) :            # 键盘上的按键  --q   --ESC
        break

cv2.destroyAllWindows() 

 

你可能感兴趣的:(工具软件,python,计算机视觉,深度学习)