black lenovo laptop computer turned on displaying man in red shirt

← INSIGHTS & PERSPECTIVES | 機器學習

OpenCV 如何用 floodFill 做魔術棒填色

介紹 OpenCV cv2.floodFill 的用途、參數、mask 規則與基本範例,用於影像分割、去噪與區域填色。

OpenCV 的 cv2.floodFill() 可以從指定種子點開始,把相連且符合條件的像素填成新顏色。這個函數很像影像編輯工具裡的魔術棒,常用在影像分割、背景處理、二值圖去噪與區域標記。

cv2.floodFill() 是什麼?

cv2.floodFill() 是 OpenCV 的泛洪填充函數。泛洪填充會從種子點往外擴張,把相鄰且落在容許差異範圍內的像素改成指定顏色。

常見用途包括圖像分割、圖像去噪、圖像修復與圖像標記。若種子點選在背景,cv2.floodFill() 可以快速把同一片背景標出來;若種子點選在物件內部,也可以用來取得物件區域。

cv2.floodFill() 參數怎麼看?

cv2.floodFill() 的重點參數是 image、mask、seedPoint、newVal、loDiff、upDiff 與 flags。mask 必須比原圖上下左右各多 1 像素,也就是寬高各多 2。

cv2.floodFill(
    image,
    mask,
    seedPoint,
    newVal,
    rect=None,
    loDiff=None,
    upDiff=None,
    flags=None,
)
參數說明
image要填充的影像,可為 8 位單通道或三通道影像
mask控制可填充區域的遮罩,尺寸需比 image 多 2 個像素
seedPoint起始種子點,格式是 (x, y)
newVal填入的新顏色,例如 BGR (0, 0, 255)
rect回傳填充區域的最小矩形
loDiff當前像素與參考像素允許的低差值
upDiff當前像素與參考像素允許的高差值
flags填充模式與連通性設定

floodFill 的 flags 要注意什麼?

cv2.floodFill() 的 flags 會影響比較方式與是否只改 mask。常用的是 4 或 8 連通、cv2.FLOODFILL_FIXED_RANGEcv2.FLOODFILL_MASK_ONLY

原文列出幾個常見旗標:cv2.FLOODFILL_FIXED_RANGE 會用種子點作固定範圍比較;cv2.FLOODFILL_MASK_ONLY 只修改 mask,不改原圖。實作時我會先從基本填色跑起,再逐步加入 tolerance 與 mask-only 模式,這樣比較容易確認是哪個參數造成結果變化。

OpenCV 魔術棒填色範例怎麼寫?

OpenCV 魔術棒填色的基本範例需要讀圖、選種子點、建立 mask,再呼叫 cv2.floodFill()。mask 的 shape 要用灰階影像高寬各加 2。

import cv2
import numpy as np

img = cv2.imread("image.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

seed_point = (100, 100)
fill_color = (0, 0, 255)
fill_mask = np.zeros((gray.shape[0] + 2, gray.shape[1] + 2), dtype=np.uint8)

cv2.floodFill(img, fill_mask, seed_point, fill_color)

cv2.imshow("image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

若結果填太多,通常是容許差異太大或種子點選錯區域。若結果填太少,則可能需要調整 loDiffupDiff,或先做平滑、二值化降低雜訊。

常見問題

Qcv2.floodFill() 的 mask 為什麼要多 2 像素?

OpenCV floodFill 的 mask 需要保留影像外圍邊界,因此尺寸必須是 (height + 2, width + 2)。如果 mask 尺寸不對,函數會直接報錯。

QseedPoint(x, y) 還是 (row, col)

seedPoint 使用 OpenCV 繪圖座標 (x, y)。這和 NumPy 用 image[row, col] 存取像素的順序不同。

QfloodFill 可以只取得區域不改原圖嗎?

可以,使用 cv2.FLOODFILL_MASK_ONLY 可以只改 mask。這在你只想取得分割區域、不想改掉原始影像時很有用。

Q魔術棒填色適合所有影像分割嗎?

不適合。cv2.floodFill() 很依賴種子點與顏色差異,若背景和物件顏色接近,可能需要先做前處理或改用輪廓、語意分割模型。

參考資料

延伸閱讀

最後更新

Mon May 08 2023 08:00:00 GMT+0800 (Taiwan Standard Time)

關於作者

Claire Chang | 企業 AI 導入與流程轉型顧問。專注於 AI Agent 架構設計、ERP 系統整合與企業 AI 治理。

首次發布:2023-05-08