计算视差图是分割图像前景和背景的有效方法。本次目标是抓住图像中的人物并丢弃背景。GradCut算法实现步骤:
1. 定義一個包含圖片主題的矩形。
2. 矩形以外的區域被自動定義為背景。
3. 背景中包含的數據作為參考,在用戶定義的矩形內區分背景區域和前景區域。
4. 高斯混合模型 (GMM) 對前景和背景進行建模,並將未定義的像素標記為可能的背景和可能的前景。
5. 圖像中的每個像素都通過虛擬邊緣虛擬連接到周圍的像素,並且每個邊緣被分配為前景或背景的概率,基於它與周圍像素的顏色相似程度。
6. 每個像素(或算法中概念化的節點)都連接到前景或背景節點。
7. 在節點連接到任一終端(背景或前景,也分別稱為源或匯)後,屬於不同終端的節點之間的邊被切割(因此得名 GrabCut)。 因此,圖像被分割成兩部分。
首先,加載我們要處理的圖像,然後創建一個填充了零的掩碼其形狀與我們加載的圖相同
import numpy as np
import cv2
from matplotlib import pyplot as plt
original = cv2.imread('img/statue_small.jpeg')
img = original.copy()
mask = np.zeros(img.shape[:2],np.uint8)
#create zero-filled background and foreground models
#創建零填充的背景和前景模型
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)
使用一個矩形來初始化 GrabCut 算法,該矩形標識我們想要隔離的主題。 因此,背景和前景模型將根據初始矩形之外的區域來確定。
rect = (100,1,421,378)
# 指定要用於初始化操作的空模型、掩碼和矩形
# 5-迭代次数
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
為了可視化 GrabCut 的結果,我們希望將背景塗成黑色並保持前景不變。 我們可以製作另一個面具來幫助我們做到這一點。 值 0 和 2(明顯且可能的背景)將轉換為 0,值 1 和 3(明顯且可能是前景)將轉換為 1。 結果將存儲在 mask2 中。 我們將原始圖像乘以 mask2 以使背景變黑(乘以 0),同時保持前景不變(乘以 1)。
1. 0 (also defined as cv2.GC_BGD) is an obvious background pixel.
2. 1 (also defined as cv2.GC_FGD) is an obvious foreground pixel.
3. 2 (also defined as cv2.GC_PR_BGD) is a probable background pixel.
4. 3 (also 3. defined as cv2.GC_PR_FGD) is a probable foreground pixel.
mask2 = np.where((mask==2) | (mask == 0),0,1,).astype('uint8')
img = img *mask2[:,:,np.newaxis]
plt.subplot(121)
plt.imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
plt.title('grabcut')
plt.xticks([])
plt.yticks([])
plt.subplot(122)
plt.imshow(cv2.cvtColor(original, cv2.COLOR_BGR2RGB))
plt.title("original")
plt.xticks([])
plt.yticks([])
plt.show()
《Learning OpenCV 4 Computer Vision with Python 3 - Third Edition》