[Python][OpenCV]使用 cv2.floodFill 移除圖像白邊教學

更新於 發佈於 閱讀時間約 11 分鐘

在圖像處理中,我們經常會遇到帶有不必要邊界的圖片,特別是從掃描文件或某些繪圖軟體導出的二值化圖像。手動裁切固然可行,但當你需要處理大量圖像時,自動化就變得至關重要。

本文將介紹如何利用 OpenCV 的 cv2.floodFill 函數,高效且準確地移除二值化圖像中的白色邊界。



結果圖

raw-image

核心概念:cv2.floodFill 洪水填充演算法

cv2.floodFill 是一種洪水填充演算法,它的基本思想是從一個指定的種子點(seed point)開始,向其周圍顏色相近的像素點蔓延,並將這些點填充為新的顏色。

在這份教學中,我們將利用這個特性來實現一個巧妙的技巧:

  1. 假設我們的圖像背景是白色的(像素值 255),而主要內容是黑色的(像素值 0)。
  2. 我們從圖像的四個邊界開始,尋找所有接觸到邊界的白色像素。
  3. 對於每一個找到的白色像素,我們將它作為種子點,啟動 floodFill 演算法。
  4. 將這些白色區域填充為黑色(像素值 0)。
  5. 因為洪水填充只會蔓延到顏色相近的區域,所以它會將所有與邊界相連的白色區域變成黑色,而不會影響到圖像內部被黑色像素包圍的白色區域。

程式碼解析

接下來,我們來詳細解析你提供的 Python 函式。

def remove_border_white(self, img):
# 假設 img 是二值化圖,白色為255,黑色為0
h, w = img.shape[:2]
# floodFill 運算需要一個比原圖長寬各多2的 mask
mask = np.zeros((h + 2, w + 2), np.uint8)

# 從四個邊界做 floodFill
# 遍歷頂部和底部邊界
for x in range(w):
if img[0, x] == 255:
cv2.floodFill(img, mask, (x, 0), 0)
if img[h - 1, x] == 255:
cv2.floodFill(img, mask, (x, h - 1), 0)

# 遍歷左側和右側邊界
for y in range(h):
if img[y, 0] == 255:
cv2.floodFill(img, mask, (0, y), 0)
if img[y, w - 1] == 255:
cv2.floodFill(img, mask, (w - 1, y), 0)

return img
  • h, w = img.shape[:2]: 取得圖像的高度和寬度。
  • mask = np.zeros((h + 2, w + 2), np.uint8): cv2.floodFill 函式需要一個額外的 mask 來標記已經被填充的區域。這個 mask 的尺寸必須比原始圖像的長寬都大 2,這是 OpenCV 函式規定的。
  • for x in range(w):: 這兩個 for 迴圈是整個演算法的關鍵。它會遍歷圖像的所有邊界像素(img[0, x]img[h-1, x]img[y, 0]img[y, w-1])。
  • if img[0, x] == 255:: 如果邊界像素是白色(值為 255),就表示這個點是與外部白色邊界相連的點。
  • cv2.floodFill(img, mask, (x, 0), 0): 呼叫 floodFill 函式。
    • img: 要操作的圖像。
    • mask: 洪水填充的掩碼。
    • (x, 0): 洪水填充的起始點(種子點)。
    • 0: 新填充的顏色值(我們將白色邊界填充為黑色)。
  • 最後,函式返回處理後的圖像。

完整的 Python 範例

現在我們將這個函式應用到一個完整的範例中。這個範例會:

  1. 使用 numpycv2 建立一個帶有白色邊界的簡單圖像。
  2. 呼叫 remove_border_white 函式來移除邊界。
  3. 使用 matplotlib.pyplot 顯示處理前後的對比圖,讓你清楚看到效果。
import cv2
import numpy as np
import matplotlib.pyplot as plt

def remove_border_white(img):
"""
使用 floodFill 演算法移除圖像中的白色邊界。

參數:
img (numpy.ndarray): 灰階或二值化圖像。假設白色為 255,黑色為 0

回傳:
numpy.ndarray: 移除白邊後的圖像。
"""
# 確保圖像為灰階,如果不是則轉換
if len(img.shape) > 2:
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

h, w = img.shape[:2]
# floodFill 需要一個比原圖大2的 mask
mask = np.zeros((h + 2, w + 2), np.uint8)

# 複製圖像,以便在不修改原圖的情況下操作
img_filled = img.copy()

# 從四個邊界做 floodFill
# 遍歷頂部和底部邊界
for x in range(w):
if img_filled[0, x] == 255:
cv2.floodFill(img_filled, mask, (x, 0), 0)
if img_filled[h - 1, x] == 255:
cv2.floodFill(img_filled, mask, (x, h - 1), 0)

# 遍歷左側和右側邊界
for y in range(h):
if img_filled[y, 0] == 255:
cv2.floodFill(img_filled, mask, (0, y), 0)
if img_filled[y, w - 1] == 255:
cv2.floodFill(img_filled, mask, (w - 1, y), 0)

return img_filled

def create_image_with_white_border():
"""
建立一個帶有白色邊界的範例圖像。
"""
height, width = 400, 600
# 建立一個全黑的圖像
image = np.zeros((height, width), dtype=np.uint8)

# 繪製一個白色矩形作為內部的白色區域
cv2.rectangle(image, (100, 100), (500, 300), 255, -1)

# 繪製一個黑色的圓形來分離內部和外部的白色
cv2.circle(image, (300, 200), 50, 0, -1)

# 在圖像周圍添加白色邊框
image[:, 10:20] = 255 # 左邊
image[:, -20:-10] = 255 # 右邊
image[10:20, :] = 255 # 上邊
image[-20:-10, :] = 255 # 下邊

return image

if __name__ == "__main__":
# 建立一個帶有白色邊界的範例圖像
original_image = create_image_with_white_border()

# 複製圖像以保留原始版本
image_to_process = original_image.copy()

# 移除白邊
processed_image = remove_border_white(image_to_process)

# 使用 matplotlib 顯示處理前後的圖像對比
plt.figure(figsize=(10, 5))

plt.subplot(1, 2, 1)
plt.imshow(cv2.cvtColor(original_image, cv2.COLOR_BGR2RGB))
plt.title('org')
plt.axis('off')

plt.subplot(1, 2, 2)
plt.imshow(cv2.cvtColor(processed_image, cv2.COLOR_BGR2RGB))
plt.title('after')
plt.axis('off')

plt.tight_layout()
plt.show()

這段程式碼首先會創建一個內部為白色、周圍有白色邊界、且中間有一個黑色圓圈的圖像。然後,它會調用 remove_border_white 函數來處理這張圖片。最後,利用 matplotlib 將原始圖和處理後的圖並排顯示,讓你清楚地看到白色邊界被移除,而圖像內部被黑色圓圈包圍的白色區域則保持不變。

希望這份教學能幫助你更好地理解並應用 cv2.floodFill 函數來解決圖像處理中的實際問題。




留言
avatar-img
留言分享你的想法!
avatar-img
螃蟹_crab的沙龍
150會員
297內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。 興趣是攝影,踏青,探索未知領域。 人生就是不斷的挑戰及自我認清,希望老了躺在床上不會後悔自己什麼都沒做。
螃蟹_crab的沙龍的其他內容
2025/08/25
交通紅綠燈辨識是一個經典的影像處理應用案例,無論是機器人導航、車輛輔助駕駛,甚至影像監控系統,都少不了這個功能。 今天我們要用 OpenCV 和 NumPy,搭配 HSV 色彩空間,快速實作一個 高穩定度的紅綠燈判斷系統。 結果圖 1. 為什麼要用 HSV 而不是 RGB 傳統 RGB
Thumbnail
2025/08/25
交通紅綠燈辨識是一個經典的影像處理應用案例,無論是機器人導航、車輛輔助駕駛,甚至影像監控系統,都少不了這個功能。 今天我們要用 OpenCV 和 NumPy,搭配 HSV 色彩空間,快速實作一個 高穩定度的紅綠燈判斷系統。 結果圖 1. 為什麼要用 HSV 而不是 RGB 傳統 RGB
Thumbnail
2025/05/02
拍攝時鏡頭有時候有粉塵或毛髮不管什麼的異物,拍攝完回家檢查圖片才發現有異物真的會氣死。 框選異物 修復後 這篇教學文章將介紹如何使用 PyQt5 和 OpenCV 來製作一款圖片異物修復工具。這個工具允許使用者載入圖片、框選異物區域,並使用 OpenCV 的 inpaint 方法來修復圖片,
Thumbnail
2025/05/02
拍攝時鏡頭有時候有粉塵或毛髮不管什麼的異物,拍攝完回家檢查圖片才發現有異物真的會氣死。 框選異物 修復後 這篇教學文章將介紹如何使用 PyQt5 和 OpenCV 來製作一款圖片異物修復工具。這個工具允許使用者載入圖片、框選異物區域,並使用 OpenCV 的 inpaint 方法來修復圖片,
Thumbnail
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
看更多
你可能也想看
Thumbnail
2025 vocus 推出最受矚目的活動之一——《開箱你的美好生活》,我們跟著創作者一起「開箱」各種故事、景點、餐廳、超值好物⋯⋯甚至那些讓人會心一笑的生活小廢物;這次活動不僅送出了許多獎勵,也反映了「內容有價」——創作不只是分享、紀錄,也能用各種不同形式變現、帶來實際收入。
Thumbnail
2025 vocus 推出最受矚目的活動之一——《開箱你的美好生活》,我們跟著創作者一起「開箱」各種故事、景點、餐廳、超值好物⋯⋯甚至那些讓人會心一笑的生活小廢物;這次活動不僅送出了許多獎勵,也反映了「內容有價」——創作不只是分享、紀錄,也能用各種不同形式變現、帶來實際收入。
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
呈上篇文章,針對單排的圖像文字增加間隔,但如果文字是雙排呢 [OpenCV][Python]OCR分割及增加間隔[單排文字]
Thumbnail
呈上篇文章,針對單排的圖像文字增加間隔,但如果文字是雙排呢 [OpenCV][Python]OCR分割及增加間隔[單排文字]
Thumbnail
本文將說明如何去辨識出圖片文字​位置及高寬。
Thumbnail
本文將說明如何去辨識出圖片文字​位置及高寬。
Thumbnail
在影像處理中,有時候我們只想特別關注某個感興趣的區域時,就是ROI的概念,擷取此範圍的圖像來做處理。 設定超過圖像邊界時就會報錯,本文主要介紹如何擷取影像的同時,避免設定錯誤造成程式崩潰的狀況。 擷取圖像示意圖 ROI程式範例 import cv2 import numpy as np
Thumbnail
在影像處理中,有時候我們只想特別關注某個感興趣的區域時,就是ROI的概念,擷取此範圍的圖像來做處理。 設定超過圖像邊界時就會報錯,本文主要介紹如何擷取影像的同時,避免設定錯誤造成程式崩潰的狀況。 擷取圖像示意圖 ROI程式範例 import cv2 import numpy as np
Thumbnail
上一篇提到利用cv2.inRangex,建立遮罩來過濾出紅球。這次我們稍微更動一下程式碼,將紅球變顏色。 [OpenCV][Python]利用cv2.inRange搭配cv2.bitwise_and過濾紅球 結果圖 將紅球改變顏色成藍球
Thumbnail
上一篇提到利用cv2.inRangex,建立遮罩來過濾出紅球。這次我們稍微更動一下程式碼,將紅球變顏色。 [OpenCV][Python]利用cv2.inRange搭配cv2.bitwise_and過濾紅球 結果圖 將紅球改變顏色成藍球
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
瞭解二值化影像的應用和程式語法,包括物體檢測和分割、邊緣檢測、圖像分析和測量、文檔辨識,以及使用cv2.threshold的參數和程式範例。
Thumbnail
瞭解二值化影像的應用和程式語法,包括物體檢測和分割、邊緣檢測、圖像分析和測量、文檔辨識,以及使用cv2.threshold的參數和程式範例。
Thumbnail
直方圖均衡化處理是一種通過調整圖像的直方圖來改變圖像外觀和質量的圖像處理技術。這通常涉及對圖像的亮度、對比度和顏色分佈進行調整 此方法對於背景和前景均亮或均暗的影像很有用。​並在曝光過度或曝光不足的照片中獲得更好的細節。
Thumbnail
直方圖均衡化處理是一種通過調整圖像的直方圖來改變圖像外觀和質量的圖像處理技術。這通常涉及對圖像的亮度、對比度和顏色分佈進行調整 此方法對於背景和前景均亮或均暗的影像很有用。​並在曝光過度或曝光不足的照片中獲得更好的細節。
Thumbnail
涉及圖像處理和計算機視覺時,色彩空間轉換是一個常見操作,應用如下: 降維: 將一張彩色圖像轉換為灰度圖像可以減少數據的維度,簡化處理過程,同時在某些情況下保留重要的視覺信息。 突顯特徵: 在某些情況下,某些色彩通道可能包含冗餘或不必要的信息,通過轉換到其他色彩空間,可以更好地突顯圖像中的重要特徵
Thumbnail
涉及圖像處理和計算機視覺時,色彩空間轉換是一個常見操作,應用如下: 降維: 將一張彩色圖像轉換為灰度圖像可以減少數據的維度,簡化處理過程,同時在某些情況下保留重要的視覺信息。 突顯特徵: 在某些情況下,某些色彩通道可能包含冗餘或不必要的信息,通過轉換到其他色彩空間,可以更好地突顯圖像中的重要特徵
Thumbnail
形態學操作在影像處理中有多種應用,特別是在處理二值化影像(黑白影像)。 在影像處理應用上,基本上都由侵蝕,膨脹這兩種方法,組合搭配而成。 常見應用場景 物體檢測與分割: 形態學操作可以用於增強或改善二值化影像中的物體邊界,使得物體的檢測和分割更加準確。
Thumbnail
形態學操作在影像處理中有多種應用,特別是在處理二值化影像(黑白影像)。 在影像處理應用上,基本上都由侵蝕,膨脹這兩種方法,組合搭配而成。 常見應用場景 物體檢測與分割: 形態學操作可以用於增強或改善二值化影像中的物體邊界,使得物體的檢測和分割更加準確。
Thumbnail
[影像處理_OpenCV Python]使用Python撰寫影像處理功能,圖片遮罩或濾除掉不要的地方,旋轉圖片 以下範例將呈現影像處理三種不同的應用: 遮罩的實現 濾除 旋轉
Thumbnail
[影像處理_OpenCV Python]使用Python撰寫影像處理功能,圖片遮罩或濾除掉不要的地方,旋轉圖片 以下範例將呈現影像處理三種不同的應用: 遮罩的實現 濾除 旋轉
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News