OpenCV第五弹-深度估计与分割

本文介绍了如何使用普通摄像头进行深度估计,包括极几何原理和计算视差图的方法,以及使用OpenCV中的GrabCut进行前景检测和分水岭算法进行图像分割的过程。
摘要由CSDN通过智能技术生成

(一)使用普通摄像头进行深度估计 

-使用(普通)深度摄像头识别前景区域和背景区域-深度摄像头/立体图像。

-深度摄像头可以计算与摄像头的距离。

-极几何:属于立体视觉几何学,从同一物体的两张不同图像提取三维信息。跟踪从摄像头到图像上每个物体的虚线,然后在第二章图像做同样的操作,并根据同一个物体对应的交叉来计算距离。

 

视差图:灰度图像,该图像的每个像素值代表物体表面的立体视差。

立体视差:从不同视角观察同一场景得到的两张图像叠放在一起,感觉是两张不同的图像,针对两张图像中两个孪生物体之间任意一对相互对应的两个像素点,可以度量像素之间的距离。近距离的物体会产生较大的立体视差,远距离的就小一些

使用极几何计算视差图,对图像中检测到的不同深度的基本表示。-提取前景部分。

条件:在不同视角相同距离拍摄两幅图像,否则计算失败。

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__":
    window_size = 5
    min_disp = 16
    num_disp = 192 - min_disp
    blockSize = window_size
    uniquenessRatio = 1
    speckleRange = 3
    speckleWindowSize = 3
    disp12MaxDiff = 200
    P1 = 600
    P2 = 2400
    imgL = cv2.imread("dep1.jpg")
    imgR = cv2.imread("dep2.jpg")
    cv2.namedWindow("disparity")
    cv2.createTrackbar("speckleRange", "disparity", speckleRange, 50, update)
    cv2.createTrackerbar("window_size", "disparity", window_size, 21, update)
    cv2.createTrackerbar(
        "speckleWindowSize", "disparity", speckleWindowSize, 200, update
    )
    cv2.createTrackerbar("uniquenessRatio", "disparity", uniquenessRatio, 50, update)
    cv2.createTrackerbar("disp12MaxDiff", "disparity", disp12MaxDiff, 250, update)
    stereo = cv2.StereoSGBM_create(
        minDisparity=min_disp,
        numDisparities=num_disp,
        blockSize=window_size,
        uniquenessRatio=uniquenessRatio,
        speckleRange=speckleRange,
        speckleWindowSize=speckleWindowSize,
        disp12MaxDiff=disp12MaxDiff,
        P1=P1,
        P2=P2,
    )
    update()
    cv2.waitKey()

 (二)使用GrabCut进行前景检测

grabCut函数:

输入图像、掩码、矩形区域、背景/前景模型、迭代次数、grabCut初始化方式

img = cv2.imread("mouse.jpg")
mask = np.zeros(img.shape[:2], np.uint8)

bgdModel = np.zeros((1, 65), np.float64) # 初始化背景模型
fgdModel = np.zeros((1, 65), np.float64) # 初始化前景模型

rect = (100, 50, 421, 378) # 用于被初始化的grabCut算法
cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)
# 进行分割

mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype("uint8")
# 创建新的掩码,将原来掩码中值为2和0 的区域设置为0,其他区域设置为1
img = img * mask2[:, :, np.newaxis]
# 根据新的掩码对图像进行遮罩操作,只保留前景像素

plt.subplot(121), plt.imshow(img)
plt.title("grabcut"), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(cv2.cvtColor(cv2.imread("mouse.jpg"), cv2.COLOR_BGR2RGB))
plt.title("original"), plt.xticks([]), plt.yticks([])
plt.show()

(三)使用分水岭算法进行图像分割

cv2.morphologyEx函数:形态学操作类型——op参数:

img = cv2.imread("luole.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)
ret1, 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)
# 计算未知区域,即既不是前景也不是背景的区域。

ret2, markers = cv2.connectedComponents(sure_fg)
# 标记连通的前景
markers = markers + 1
# 增加标签数量
markers[unknown == 255] = 0

markers = cv2.watershed(img, markers)
# 使用Watershed算法标记图片
img[markers == -1] = [255, 0, 0]
plt.imshow(img)
plt.show()

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值