opencv計算機視覺學習筆記三

 

第四章 深度估計和分割python

1 捕獲深度攝像頭的幀算法

深度圖  灰度  每一個像素都是攝像頭到物體表面的距離 毫米windows

點雲圖  彩色  每種顏色對應一個維度空間  米數組

視差圖  灰度  每一個像素表明物體表面的立體視差 近大遠小函數

有效深度掩模一個給定像素的深度信息是否有效ui

 

2 從視差圖中獲得掩模spa

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2016/12/1 10:16
# @Author  : Retacn
# @Site    : 深度攝像頭數據的處理
# @File    : depth.py
# @Software: PyCharm
__author__ = "retacn"
__copyright__ = "property of mankind."
__license__ = "CN"
__version__ = "0.0.1"
__maintainer__ = "retacn"
__email__ = "zhenhuayue@sina.com"
__status__ = "Development"

import numpy as np


#設備
CAP_OPENNI=900
CAP_OPENNI_ASUS=910

#通道(基於浮點數的距離)
CAP_OPENNI_DEPTH_MAP=0

#會獲得bgr圖像
CAP_OPENNI_POINT_CLOUD_MAP=1

#XYZ
CAP_OPENNI_DISPARITY_MAP=2

#
CAP_OPENNI_DISPARITY_MAP_32F=3
CAP_OPENNI_VALID_DEPTH_MASK=4

CAP_OPENNI_BGR_IMAGE=5
CAP_OPENNI_GRAY_IMAGE=6

#生成掩模
def createMedianMask(disparityMap,#視差圖
                     validDepthMask,#有效深度掩模
                     rect=None):#矩形
    if  rect is not None:
        x,y,w,h=rect
        disparityMap=disparityMap[y:y+h,x:x+w]
        validDepthMask=validDepthMask[y:y+h,x:x+w]
    #獲得中值
    median=np.median(disparityMap)
    #生成掩模,逐像素進行布爾操做
    return np.where((validDepthMask==0) | (abs(disparityMap-median)<12),#值爲真假的數組,當有效視差與平均視差>=12,看做噪聲
                    1.0,#爲真時,數組相應元素爲該值
                    0.0)#爲假時,爲該值

 

3 對複製操做進行掩模orm

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2016/12/1 10:22
# @Author  : Retacn
# @Site    : 矩形區域複製
# @File    : rects.py
# @Software: PyCharm
__author__ = "retacn"
__copyright__ = "property of mankind."
__license__ = "CN"
__version__ = "0.0.1"
__maintainer__ = "retacn"
__email__ = "zhenhuayue@sina.com"
__status__ = "Development"

import cv2
import numpy as np
from Three import utils

#對複製操做執行掩模
def copyRect(src,
             dst,
             srcRect,
             dstRect,
             mask=None,#掩模參數,掩模要和圖像有相同的通道數
             interpolation=cv2.INTER_LINEAR):#插值方法爲線性插值
    x0,y0,w0,h0=srcRect
    x1,y1,w1,h1=dstRect

    #若是掩模爲空,則執行復制操做
    if mask is None:
        dst[y1:y1+h1,x1:x1+w1]=cv2.resize(src[y0:y0+h0,y0:y0+h0],#源圖像
                                          (w1,h1),#目標圖像
                                          interpolation=interpolation)#插值方法
    else:
        #若是掩模爲單通道,則複製通道
        if not utils.isGray(src):
            mask=mask.repeat(3).reshape(h0,w0,3)
        dst[y1:y1+h1,x1:x1+w1]=np.where(cv2.resize(mask,(w1,h1),interpolation=cv2.INTER_NEAREST),
                                        cv2.resize(src[y0:y0+h0,x0:x0+w0],(w1,h1),interpolation=interpolation),
                                        dst[y1:y1 + h1, x1:x1 + w1]
                                        )

#一組矩形的循環交換
def swqpRects(src,dst,rects,masks=None,interpolation=cv2.INTER_LINEAR):
    if dst is not src:
        dst[:]=src

    numRects=len(rects)
    if numRects<2:
        return     if masks is None:
        masks=[None]*numRects

    x,y,w,h=rects[numRects-1]
    temp=src[y:y+h,x:x+w].copy()

    i=numRects-2
    while i>=0:
        copyRect(src,dst,rects[i],rects[i+1],masks[i],interpolation)
        i-=1
    copyRect(temp,dst,(0,0,w,h),rects[0],masks[numRects-1],interpolation)

 

 4 使用普通攝像頭進行深試評估事件

 

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2016/12/1 11:40
# @Author  : Retacn
# @Site    : 使用普通攝像頭進行深試估計
# @File    : commonCamera2Depth.py
# @Software: PyCharm
__author__ = "retacn"
__copyright__ = "property of mankind."
__license__ = "CN"
__version__ = "0.0.1"
__maintainer__ = "retacn"
__email__ = "zhenhuayue@sina.com"
__status__ = "Development"

import cv2
import numpy as np

def update(val=0):
    stereo.setBlockSize(cv2.getTrackbarPos('window_size','disparity'))
    stereo.setUniquenessRatio(cv2.getTrackbarPos('uniquenessRatio','disparity'))
    stereo.setSpeckleWindowSize(cv2.getTrackbarPos('speckleWindowSize','disparity'))
    stereo.setSpeckleRange(cv2.getTrackbarPos('speckleRange','disparity'))
    stereo.setDisp12MaxDiff(cv2.getTrackbarPos('disp12MaxDiff','disparity'))
    print('computing disparity...')
    disp = stereo.compute(imgL, imgR).astype(np.float32) / 16.0
    cv2.imshow('left', imgL)
    cv2.imshow('disparity', (disp - min_disp) / num_disp)

if __name__=='__main__':
    windows_size=5 #一個匹配塊的大小,大於1的奇數
    min_disp=16 #最小視差值
    num_disp=192-min_disp #最大視差值和最小視差值的差
    blockSize=windows_size
    uniquenessRatio=1
    speckleRange=3 #每一個已鏈接部分的最大視差變化
    speckleWindowSize=3 #平滑視差區域的最大窗口尺寸
    disp12MaxDiff=200
    P1=600 #控制視差圖平滑度有第一個參數
    P2=2400#第二個參數,值越大視差圖越平滑

    #讀入圖像
    imgL=cv2.imread('../imgl.jpg')
    imgR=cv2.imread('../imgr.jpg')

    cv2.namedWindow('disparity')
    cv2.createTrackbar('speckleRange','disparity',speckleRange,50,update)
    cv2.createTrackbar('window_size','disparity',windows_size,21,update)
    cv2.createTrackbar('speckleWindowSize','disparity',speckleWindowSize,200,update)
    cv2.createTrackbar('uniquenessRatio','disparity',uniquenessRatio,50,update)
    cv2.createTrackbar('disp12MaxDiff','disparity',disp12MaxDiff,250,update)

    stereo=cv2.StereoSGBM_create(minDisparity=min_disp,
                                 numDisparities=num_disp,
                                 blockSize=blockSize,
                                 uniquenessRatio=uniquenessRatio,
                                 speckleRange=speckleRange,
                                 speckleWindowSize=speckleWindowSize,
                                 disp12MaxDiff=disp12MaxDiff,
                                 P1=P1,
                                 P2=P2)

    update()
    cv2.waitKey()

 

 

5 使用分水嶺和grabcut算法進行物體分割utf-8

 A 使用brabcut進行前景檢測

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2016/12/2 11:17
# @Author  : Retacn
# @Site    : 使用grubCut進行前景檢測
# @File    : grabcutNew.py
# @Software: PyCharm
__author__ = "retacn"
__copyright__ = "property of mankind."
__license__ = "CN"
__version__ = "0.0.1"
__maintainer__ = "retacn"
__email__ = "zhenhuayue@sina.com"
__status__ = "Development"

import cv2
import numpy as np
import sys

# 定義顏色
BLUE = [255, 0, 0# rectangle color
RED = [0, 0, 255# PR BG
GREEN = [0, 255, 0# PR FG
BLACK = [0, 0, 0# sure BG
WHITE = [255, 255, 255# sure FG

DRAW_BG = {'color': BLACK, 'val': 0}
DRAW_FG = {'color': WHITE, 'val': 1}
DRAW_PR_FG = {'color': GREEN, 'val': 3}
DRAW_PR_BG = {'color': RED, 'val': 2}

# 設置標誌位
rect = (0, 0, 1, 1# 隔離對像矩形
drawing = False  # 繪製標誌位
rectangle = False  # 矩形繪製標誌
rect_over = False  # 檢查隔離矩形是否繪製
rect_or_mask = 100  # 掩模模式
value = DRAW_FG  #
thickness = # 畫筆寬度


# 自定義鼠標回調函數
def onmouse(event, x, y, flags, param):
    # 定義全局變量
    global img, img2, drawing, value, mask, rectangle, rect, rect_or_mask, ix, iy, rect_over

    # 繪製隔離矩形
    if event == cv2.EVENT_RBUTTONDOWN:  # 鼠標右健按下,開始繪製矩形
        rectangle = True         ix, iy = x, y

    elif event == cv2.EVENT_MOUSEMOVE:  # 鼠標移動事件
        if rectangle == True# 繪製矩形
            img = img2.copy()
            cv2.rectangle(img# 源圖像
                          (ix, iy)# 開始點
                          (x, y)# 結束點
                          BLUE# 畫筆顏色
                          2# 畫筆寬度
            rect = (min(ix, x), min(iy, y), abs(ix - x), abs(iy - y))
            rect_or_mask = 0

    elif event == cv2.EVENT_RBUTTONUP:  # 右鍵擡起
        rectangle = False  # 設置標誌位,矩形繪製完成
        rect_over = True         cv2.rectangle(img, (ix, iy), (x, y), BLUE, 2)
        rect = (min(ix, x), min(iy, y), abs(ix - x), abs(iy - y))
        rect_or_mask=0
        print('按下 n , 開始繪製')

    #繪製隔離圓形
    if event==cv2.EVENT_LBUTTONDOWN: #左鍵按下
        if rect_over==False:
            print("請先繪製圓形")
        else:
            drawing=True             cv2.circle(img,(x,y),thickness,value['color'],-1)
            cv2.circle(mask,(x,y),thickness,value['color'],-1)

    elif event==cv2.EVENT_MOUSEMOVE:
        if drawing==True:
            cv2.circle(img, (x, y), thickness, value['color'], -1)
            cv2.circle(mask, (x, y), thickness, value['color'], -1)

    elif event==cv2.EVENT_LBUTTONUP:
        if drawing==True:
            drawing=False             cv2.circle(img, (x, y), thickness, value['color'], -1)
            cv2.circle(mask, (x, y), thickness, value['color'], -1)

if __name__ == '__main__':
    fileName = '../test1.jpg'

    img = cv2.imread(fileName)
    img2 = img.copy()
    mask = np.zeros(img.shape[:2], dtype=np.uint8)
    output = np.zeros(img.shape, np.uint8)

    # 定義輸入輸出窗口
    cv2.namedWindow("output")
    cv2.namedWindow('input')
    #輸出窗口註冊鼠標事件
    cv2.setMouseCallback('input', onmouse)
    cv2.moveWindow('input',img.shape[1]+10,90)

    print("操做指南:\n")
    print('使用鼠標右健在源圖像中繪製矩形\n')

    while(1):
        #顯示圖像
        cv2.imshow('output',output)
        cv2.imshow('input',img)
        k=0xFF&cv2.waitKey(1)

        if k==27: #ESC鍵退出
            break         elif k==ord('0'):#繪製背景
            print("左鍵繪製background標識區域 \n")
            value=DRAW_BG
        elif k==ord('1'):#繪製前景
            print('左鍵繪製foreground標識區域 \n')
            value=DRAW_FG
        elif k==ord('2'):
            value=DRAW_PR_BG
        elif k == ord('3'):
            value = DRAW_PR_FG
        elif k==ord('s'):# 保存圖像
            bar=np.zeros((img.shape[0],5,3),np.uint8)
            res=np.hstack((img2.bar,img,bar,output))
            cv2.imwrite('grabcut_output.png',res)
            print('保存圖像')
        elif k==ord('r'):#重置
            print('開始重置 \n')
            rect = (0, 0, 1, 1)
            drawing = False             rectangle = False             rect_or_mask = 100
            rect_over = False             value = DRAW_FG
            img = img2.copy()
            mask = np.zeros(img.shape[:2], dtype=np.uint8)
            output = np.zeros(img.shape, np.uint8)
        elif k == ord('n'):  # 圖像截取
            print(""" For finer touchups, mark foreground and background after pressing keys 0-3
                   and again press 'n' \n""")
            if (rect_or_mask == 0):  # 設置掩模
                bgdmodel = np.zeros((1, 65), np.float64)
                fgdmodel = np.zeros((1, 65), np.float64)
                cv2.grabCut(img2, mask, rect, bgdmodel, fgdmodel, 1, cv2.GC_INIT_WITH_RECT)
                rect_or_mask = 1
            elif rect_or_mask == 1# 設置掩模
                bgdmodel = np.zeros((1, 65), np.float64)
                fgdmodel = np.zeros((1, 65), np.float64)
                cv2.grabCut(img2, mask, rect, bgdmodel, fgdmodel, 1, cv2.GC_INIT_WITH_MASK)

        mask2 = np.where((mask == 1) + (mask == 3), 255, 0).astype('uint8')
        output = cv2.bitwise_and(img2, img2, mask=mask2)

    cv2.destroyAllWindows()

 

 

B 使用分水嶺算法進行圖像分割

示例代碼以下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2016/12/2 12:21
# @Author  : Retacn
# @Site    : 使用分水嶺算法進行圖像分割
# @File    : watershed.py
# @Software: PyCharm
__author__ = "retacn"
__copyright__ = "property of mankind."
__license__ = "CN"
__version__ = "0.0.1"
__maintainer__ = "retacn"
__email__ = "zhenhuayue@sina.com"
__status__ = "Development"

import cv2
import numpy as np
from matplotlib import pyplot as plt

img =cv2.imread('../test1.jpg')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#轉換爲灰度圖,設置閾值
ret,thresh=cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

kernel=np.ones((3,3),np.uint8)
opening=cv2.morphologyEx(thresh,#源圖像
                         cv2.MORPH_OPEN, #開運算
                         kernel, #核
                         iterations=2)#迭代次數

#取得肯定的前景區域
sure_bg=cv2.dilate(opening,kernel,iterations=3)
dist_transform=cv2.distanceTransform(opening,cv2.DIST_L2,5)
ret,sure_fg=cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)

sure_fg=np.uint8(sure_fg)
unknown=cv2.subtract(sure_bg,sure_fg)

ret,markers=cv2.connectedComponents(sure_fg)
markers=markers+1
markers[unknown==255]=0

markers=cv2.watershed(img,markers)
img[markers==-1]=[255,0,0]
plt.imshow(img)
plt.show()
相關文章
相關標籤/搜索