[OpenCV][Python]使用GrabCut 來去背

更新 發佈閱讀 12 分鐘

iPhone也有去背的功能,那麼OpenCV能不能做到這件事呢?,答案是可以的

  • 如果圖像背景簡單且與前景有明顯的顏色區分,可以使用 色彩空間轉換閥值分割
  • 如果背景較為複雜一點點,但你可以提供一個大致的前景位置,則可以使用 GrabCut

結果圖

但在背景相當複雜的情況下,結果就不太好,若要好又要設很多條件才能完美切割。

raw-image


GrabCut 是一種強大的前景提取演算法,特別適合處理具有複雜背景的圖像分割問題。它基於圖割(Graph Cut)的技術進行迭代優化,能夠在給定前景物體的大致區域後,自動分割出前景。

原文連結


GrabCut 演算法的核心原理

GrabCut 演算法基於 最大流最小割 的圖論技術。圖像中的每個像素被視為圖中的一個節點,而前景和背景被視為兩個特殊的節點:源點(Source)匯點(Sink)。演算法通過最大化像素到這兩個特殊點的連接來進行優化。這意味著,演算法會嘗試尋找一個切割線,將圖像中的節點劃分為前景和背景。

  • 數學模型:GrabCut 將前景和背景的像素顏色分布建模為 高斯混合模型(GMM)。在每次迭代中,算法會根據當前的分割結果不斷更新 GMM,並進一步優化分割。

cv2.grabCut 函數的語法:

cv2.grabCut(img, mask, rect, bgdModel, fgdModel, iterCount, mode)

各個參數說明:

  1. img
    • 類型:np.ndarray(輸入圖像)
    • 說明:這是需要進行分割的原始圖像。它應該是一個彩色圖像(通常是 BGR 格式)。演算法將根據這個圖像來計算前景和背景的分割。
    • 用途:分割目標圖像。
  2. mask
    • 類型:np.ndarray(遮罩)
    • 說明:這是一個與圖像大小相同的單通道遮罩圖像,表示哪些像素是前景、背景或不確定的區域。它通常在初始執行時全為 0。
    • 當使用 cv2.GC_INIT_WITH_RECT 模式時,矩形內的像素會被初始化為可能的前景,矩形外的像素會被初始化為背景。
    • 遮罩的值可以為以下幾個:
      cv2.GC_BGD(0):確定的背景像素。
      cv2.GC_FGD(1):確定的前景像素。
      cv2.GC_PR_BGD(2):可能的背景像素。
      cv2.GC_PR_FGD(3):可能的前景像素。
    • 用途:分割過程中會不斷更新這個遮罩,將像素標識為前景或背景
  3. rect
    • 類型:tuple(矩形邊界,格式為 (x, y, w, h))
    • 說明:用來定義包含前景物體的大致區域。矩形內的像素被初始化為前景,矩形外的像素被初始化為背景。該矩形不需要完全精確包圍前景,但要盡量包含整個前景,避免太多背景。此參數僅在 cv2.GC_INIT_WITH_RECT 模式下使用。
    • 用途:指定初始前景和背景區域。
  4. bgdModel(背景模型):
    • 類型:np.ndarray,大小為 (1, 65),浮點數類型。
    • 說明:這是背景模型,它是由 GrabCut 演算法內部計算並用來描述背景顏色分布的數據結構。該陣列在運行之前需要初始化為全 0。演算法在運行過程中會更新此模型。
    • 用途:演算法內部用來表示背景的顏色統計模型,外部不需要干預。
  5. fgdModel(前景模型):
    • 類型:np.ndarray,大小為 (1, 65),浮點數類型。
    • 說明:這是前景模型,它是由 GrabCut 演算法內部計算並用來描述前景顏色分布的數據結構。該陣列在運行之前需要初始化為全 0。演算法在運行過程中會更新此模型。
    • 用途:演算法內部用來表示前景的顏色統計模型,外部不需要干預。
  6. iterCount
    • 類型:整數
    • 說明:表示演算法應該進行的迭代次數。演算法是一個迭代優化過程,每次迭代會優化分割結果。通常 5-10 次迭代已經能夠產生滿意的結果。如果結果不理想,增加迭代次數可能會改善結果。
    • 用途:控制演算法的收斂過程。
  7. mode
    • 類型:int,表示初始化模式。
    • 說明:這個參數指定了 GrabCut 的初始化方式,有兩種模式:cv2.GC_INIT_WITH_RECT:使用矩形來初始化前景和背景。這是最常用的模式,矩形內的像素被初始化為前景,矩形外的像素被初始化為背景。cv2.GC_INIT_WITH_MASK:使用遮罩來初始化前景和背景。如果遮罩已經部分標定了前景和背景區域,可以使用這種模式進行更精確的初始化。
    • 用途:指定 GrabCut 的初始化方法,是使用矩形還是掩膜進行初始分割。

使用矩形來初始化前景和背景

範例

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

# 顯示圖像的函數
def show_image(image, title="Image"):
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title(title)
plt.axis('off') # 不顯示座標軸
plt.show()

# 讀取圖像
image_path = 'your_image_path.png' # 替換成你的圖像路徑
img = cv2.imread(image_path)

# 初始化掩膜
mask = np.zeros(img.shape[:2], np.uint8)

# 背景和前景模型(由 GrabCut 需要)
bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)

# 定義一個矩形來包含前景物體
rect = (350, 200, 300, 300) # 根據圖像大小進行調整 x,y,w,h
# 在原圖上畫出矩形框
img_with_rect = img.copy()
cv2.rectangle(img_with_rect, (rect[0], rect[1]), (rect[0] + rect[2], rect[1] + rect[3]), (0, 255, 0), 2)

# 顯示畫出矩形框的圖像
show_image(img_with_rect, "Image with Rectangle")
# 執行 GrabCut 算法
cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 10, cv2.GC_INIT_WITH_RECT)

# 修改掩膜以提取前景
mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
grabcut_result = img * mask2[:, :, np.newaxis]

# 顯示原圖和 GrabCut 結果
show_image(img, "Original Image")
show_image(grabcut_result, "GrabCut Foreground Extraction")

原圖

raw-image

矩形位置

框選想保留的物件位置

raw-image

GrabCut 結果

raw-image

使用遮罩來初始化前景和背景

先標示前景與背景的區域,設定一個矩形範圍。

範例

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

# 顯示圖像的函數
def show_image(image, title="Image"):
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title(title)
plt.axis('off') # 不顯示座標軸
plt.show()

# 讀取圖像
image_path = 'your_image_path.png' # 替換成你的圖像路徑
img = cv2.imread(image_path)

# 初始化掩膜
mask = np.zeros(img.shape[:2], np.uint8)

# 背景和前景模型(由 GrabCut 需要)
bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)

# 定義一個矩形來包含前景物體
rect = (350, 200, 300, 300) # 根據圖像大小進行調整 x,y,w,h

# 手動調整掩膜來改善前景檢測
mask[200:500, 350:650] = cv2.GC_FGD # 標記這部分是確定的前景
mask[800:1000, 40:300] = cv2.GC_BGD # 標記這部分是確定的背景

# 再次執行 GrabCut
cv2.grabCut(img, mask, None, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_MASK)

# 修改掩膜以提取前景
mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
grabcut_result = img * mask2[:, :, np.newaxis]

# 顯示原圖和 GrabCut 結果
show_image(img, "Original Image")
show_image(grabcut_result, "GrabCut Foreground Extraction")
raw-image

遮罩的進階用法

設定符合顏色範圍的部分,設定為前景,以下範例設定為紅色的部分,就可只截取氣球的部分了

# 初始化掩膜
mask = np.zeros(img.shape[:2], np.uint8)
# 將圖像轉換為 RGB 色彩空間
RGB_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 定義顏色範圍
lower_color = np.array([150, 0, 0]) # 低閥值
upper_color = np.array([255, 70, 70]) # 高閥值

# 創建遮罩,篩選出符合顏色範圍的部分
mask_red = cv2.inRange(RGB_img, lower_color, upper_color)

# 初始化 GrabCut 所需的掩膜
mask_grabcut = np.zeros(img.shape[:2], np.uint8)

# 使用篩選出的顏色區域更新掩膜,將篩選出的部分設為"可能前景"(cv2.GC_PR_FGD
mask_grabcut[mask_red > 0] = cv2.GC_PR_FGD
raw-image













留言
avatar-img
螃蟹_crab的沙龍
161會員
317內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。 興趣是攝影,踏青,探索未知領域。 人生就是不斷的挑戰及自我認清,希望老了躺在床上不會後悔自己什麼都沒做。
螃蟹_crab的沙龍的其他內容
2025/03/24
在影像處理或機器學習的應用中,我們常常需要將影片逐幀擷取出來,進一步進行辨識或分析。 本篇教學將示範如何使用 Python + OpenCV 來: ✅ 讀取 MP4 影片 測試影片可由下方超連結下載,從file-examples.com下載 file-examples.com 是一個 免費提
Thumbnail
2025/03/24
在影像處理或機器學習的應用中,我們常常需要將影片逐幀擷取出來,進一步進行辨識或分析。 本篇教學將示範如何使用 Python + OpenCV 來: ✅ 讀取 MP4 影片 測試影片可由下方超連結下載,從file-examples.com下載 file-examples.com 是一個 免費提
Thumbnail
2024/10/11
本文將指導你如何修改現有的 OpenCV 程式碼,使其利用 CUDA 加速進行深度神經網絡(DNN)推理,如超分辨率圖像放大任務。這將顯著提升運行速度,特別是在高分辨率圖像處理中。 在CMake上這選項要開,才可支援DNN模組。 CMake編譯OpenCV教學文 連結 [OpenCV][Py
Thumbnail
2024/10/11
本文將指導你如何修改現有的 OpenCV 程式碼,使其利用 CUDA 加速進行深度神經網絡(DNN)推理,如超分辨率圖像放大任務。這將顯著提升運行速度,特別是在高分辨率圖像處理中。 在CMake上這選項要開,才可支援DNN模組。 CMake編譯OpenCV教學文 連結 [OpenCV][Py
Thumbnail
2024/10/10
OpenCV 提供了專門針對 CUDA 優化的模組,這些模組使用 cv2.cuda 命名空間,並且可以直接使用 GPU 進行加速。,cv2.cuda 模塊需要在 OpenCV 編譯時啟用 CUDA 支援才能使用。 本文主要比較經過CMAKE重新編譯OpenCV使其支援Cuda,原OpenCV只支援
Thumbnail
2024/10/10
OpenCV 提供了專門針對 CUDA 優化的模組,這些模組使用 cv2.cuda 命名空間,並且可以直接使用 GPU 進行加速。,cv2.cuda 模塊需要在 OpenCV 編譯時啟用 CUDA 支援才能使用。 本文主要比較經過CMAKE重新編譯OpenCV使其支援Cuda,原OpenCV只支援
Thumbnail
看更多
你可能也想看
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
我們將學習如何使用 Python 和 OpenCV 實現圖像的主色提取與重新著色。 以下的程式碼展示了如何通過 KMeans 聚類演算法分析圖像,提取 HSV 色彩空間中的主色,並將圖像重新著色,提取想偵測的物件的顏色。 在官網案例,實作為RGB色彩空間,但如果套用HSV色彩空間則會因為H色
Thumbnail
我們將學習如何使用 Python 和 OpenCV 實現圖像的主色提取與重新著色。 以下的程式碼展示了如何通過 KMeans 聚類演算法分析圖像,提取 HSV 色彩空間中的主色,並將圖像重新著色,提取想偵測的物件的顏色。 在官網案例,實作為RGB色彩空間,但如果套用HSV色彩空間則會因為H色
Thumbnail
在 Photoshop 中錄製一個自動去背的動作,讓你能批量處理圖片。步驟包括設定顏色範圍、填充背景和物件顏色,還有如何保存和批量處理多個檔案,節省時間。這個方法特別適合背景顏色明顯區分的圖片,並提供一些實用的小技巧,讓操作更簡單輕鬆。
Thumbnail
在 Photoshop 中錄製一個自動去背的動作,讓你能批量處理圖片。步驟包括設定顏色範圍、填充背景和物件顏色,還有如何保存和批量處理多個檔案,節省時間。這個方法特別適合背景顏色明顯區分的圖片,並提供一些實用的小技巧,讓操作更簡單輕鬆。
Thumbnail
[OpenCV][Python]使用GrabCut 來去背 在上篇文章提到如何用GrabCut 來去背,但都是處於比較基礎的方式,讓演算法自行判斷前景背景,本文主要說明,使用設定參數讓演算法計算得更加準確,可根據UI上的圖顯示,用滑鼠畫區域來設定參考的背景與前景。 UI圖顯示 步驟,先載圖,在
Thumbnail
[OpenCV][Python]使用GrabCut 來去背 在上篇文章提到如何用GrabCut 來去背,但都是處於比較基礎的方式,讓演算法自行判斷前景背景,本文主要說明,使用設定參數讓演算法計算得更加準確,可根據UI上的圖顯示,用滑鼠畫區域來設定參考的背景與前景。 UI圖顯示 步驟,先載圖,在
Thumbnail
iPhone也有去背的功能,那麼OpenCV能不能做到這件事呢?,答案是可以的 如果圖像背景簡單且與前景有明顯的顏色區分,可以使用 色彩空間轉換 或 閥值分割。 如果背景較為複雜一點點,但你可以提供一個大致的前景位置,則可以使用 GrabCut。 結果圖 但在背景相當複雜的情況下,結果就不太
Thumbnail
iPhone也有去背的功能,那麼OpenCV能不能做到這件事呢?,答案是可以的 如果圖像背景簡單且與前景有明顯的顏色區分,可以使用 色彩空間轉換 或 閥值分割。 如果背景較為複雜一點點,但你可以提供一個大致的前景位置,則可以使用 GrabCut。 結果圖 但在背景相當複雜的情況下,結果就不太
Thumbnail
在影像辨識中,若遇到物件與背景難以分辨的狀況下,先做一下色彩分析,知道了色彩強度階層上的像素數,有助於了解後續需要做什麼處理,比較好分割出辨識物。 若想辨識的物件與背景的RGB值過於接近,也比較好說明此狀況,為什麼較難分割出物件。 成果呈現 第一張圖:左邊為原圖,右邊為分析結果的圖,用其他顏
Thumbnail
在影像辨識中,若遇到物件與背景難以分辨的狀況下,先做一下色彩分析,知道了色彩強度階層上的像素數,有助於了解後續需要做什麼處理,比較好分割出辨識物。 若想辨識的物件與背景的RGB值過於接近,也比較好說明此狀況,為什麼較難分割出物件。 成果呈現 第一張圖:左邊為原圖,右邊為分析結果的圖,用其他顏
Thumbnail
用小畫家隨意畫三個圈分別用紅藍綠,我們利用cv2.inRange與搭配cv2.bitwise_and,將紅球過濾出來吧。 程式範例 因為OpenCV中cv2.imread讀取圖檔預設讀取是為[B,G,R]的格式,所以設置紅色範圍要注意設定在R的範圍內。
Thumbnail
用小畫家隨意畫三個圈分別用紅藍綠,我們利用cv2.inRange與搭配cv2.bitwise_and,將紅球過濾出來吧。 程式範例 因為OpenCV中cv2.imread讀取圖檔預設讀取是為[B,G,R]的格式,所以設置紅色範圍要注意設定在R的範圍內。
Thumbnail
涉及圖像處理和計算機視覺時,色彩空間轉換是一個常見操作,應用如下: 降維: 將一張彩色圖像轉換為灰度圖像可以減少數據的維度,簡化處理過程,同時在某些情況下保留重要的視覺信息。 突顯特徵: 在某些情況下,某些色彩通道可能包含冗餘或不必要的信息,通過轉換到其他色彩空間,可以更好地突顯圖像中的重要特徵
Thumbnail
涉及圖像處理和計算機視覺時,色彩空間轉換是一個常見操作,應用如下: 降維: 將一張彩色圖像轉換為灰度圖像可以減少數據的維度,簡化處理過程,同時在某些情況下保留重要的視覺信息。 突顯特徵: 在某些情況下,某些色彩通道可能包含冗餘或不必要的信息,通過轉換到其他色彩空間,可以更好地突顯圖像中的重要特徵
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News