OpenCV——使用GrabCut算法进行物体分割

GrabCut算法的实现步骤为:

  1. 在图片中定义含有(一个或多个)物体的矩形。
  2. 矩形外的区域被自动认为是背景。
  3. 对于用户定义的矩形区域,可用背景中的数据来区别它里面的前景和背景区域。
  4. 用高斯混合模型(Gaussians Mixture Model,GMM)来对背景和前景建模,并将未定义的像素标记为可能的前景或背景。
  5. 图像中的每一个像素都被看作通过虚拟边与周围像素相连接,而每条边都有一个属于前景或背景的概率,这基于它与周围像素颜色上的相似性。
  6. 每一个像素(即算法中的节点)会与一个前景或背景节点连接。
  7. 在节点完成连接后(可能与背景或前景连接),若节点之间的边属于不同终端(即一个节点属于前景,一个节点属于背景),则会切断它们之间的边,这就能将图像各部分分隔出来。

下面的示例代码主要有这几步:

  1. 加载想要处理的图像,然后创建一个与图像大小相同的掩模,并用0填充。
  2. 创建以0填充的前景和背景模型。
  3. 准备一个标识出想要隔离的对象的矩形来初始化GrabCut算法。
  4. 使用指定的空模型和掩模来运行GrabCut算法。
  5. cv2.grabCut()的第六个参数是算法迭代的次数,执行完算法之后,掩模已经变成了包含0~3的值,其中值为0和2的为背景,值为1和3的为前景。
  6. 使用matplotlib来并排展示处理前后的图像。

示例代码如下:

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

img = cv2.imread('statue_small.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, 1, 421, 378)
cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)

mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
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('statue_small.jpg'), cv2.COLOR_BGR2RGB))
plt.title("original"), plt.xticks([]), plt.yticks([])
plt.show()

原图像statue_small.jpg为:

OpenCV——使用GrabCut算法进行物体分割_第1张图片

运行结果为:

OpenCV——使用GrabCut算法进行物体分割_第2张图片


想了解更多关于数字图像处理:数字图像处理专栏

你可能感兴趣的:(数字图像处理,Python,OpenCV,数字图像处理)