🦀【影像處理新手必看】二值圖像型態與像素值的陷阱:端點偵測踩雷全紀錄

更新 發佈閱讀 8 分鐘

在 Python 影像處理(OpenCV、skimage)專案中,二值圖像的像素值與資料型態常常讓人踩雷!

本文以「骨架端點偵測」為例,帶你認識這個常見問題、如何避免,以及正確的寫法。


1️⃣ 問題背景

我們常會用**骨架化(skeletonization)**來分析物件形狀,並想找出骨架的端點(endpoints)。端點偵測常見兩種方法:

找到的結果是一致的

差別在效率

vocus|新世代的創作平台
vocus|新世代的創作平台


  • filter2D 卷積法(適合 0/1 二值圖)
  • for-loop 8鄰域法(適合 0/255 二值圖)

7x5「數字 1」骨架(端點明顯版)

0/1 格式(for filter2d)

0 0 0 0 0
0 0 1 0 0端點 (1,2)
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 0 0 0

0/255 格式(for loop)

  0   0   0   0   0
0 0 255 0 0端點 (1,2)
0 0 255 0 0
0 0 255 0 0
0 0 255 0 0
0 0 255 0 0
0 0 0 0 0

端點位置

  • (1,2) (第二列第三行)
  • (5,2) (第六列第三行)

這兩個點就是骨架的端點,因為它們只連接一個骨架點。


視覺化標註

0 0 0 0 0
0 0 x 0 0端點 (1,2)
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 x 0 0端點 (5,2)
0 0 0 0 0

但如果圖像型態搞錯,就會發生「偵測不到端點」的慘劇!


2️⃣ 常見踩雷情境

範例一:filter2D 只適用 0/1 圖像

def find_skeleton_endpoints_filter2d(skeleton: np.ndarray) -> np.ndarray:
kernel = np.array([[1,1,1], [1,10,1], [1,1,1]], dtype=np.uint8)
filtered = cv2.filter2D(skeleton, -1, kernel)
endpoints = (filtered == 11).astype(np.uint8)
return endpoints

錯誤用法:

skeleton = skeletonize(binary > 0).astype(np.uint8) * 255  # 這時像素值是 0/255
endpoints = find_skeleton_endpoints_filter2d(skeleton) # ❌ 找不到端點

正確用法:

skeleton = skeletonize(binary > 0).astype(np.uint8)        # 這時像素值是 0/1
endpoints = find_skeleton_endpoints_filter2d(skeleton) # ✅ 正常偵測

範例二:for-loop 8鄰域法適用 0/255

def find_skeleton_endpoints_loop(skeleton: np.ndarray) -> list:
h, w = skeleton.shape
endpoints = []
for y in range(1, h - 1):
for x in range(1, w - 1):
if skeleton[y, x] == 255:
neighbors = skeleton[y - 1:y + 2, x - 1:x + 2]
num_neighbors = np.sum(neighbors == 255) - 1
if num_neighbors == 1:
endpoints.append((y, x))
return endpoints

這裡預設骨架點是 255,如果你傳進去的是 0/1 圖像,會找不到端點!


3️⃣ 解決方法與最佳實踐

✅ 1. 明確轉換像素值

  • filter2D 方法前,請轉成 0/1:
    skeleton_01 = (skeleton > 0).astype(np.uint8)
  • for-loop 方法前,請轉成 0/255:
    skeleton_255 = (skeleton > 0).astype(np.uint8) * 255

✅ 2. 明確註記每個函式的輸入格式

  • 在每個函式 docstring 註明「輸入需為 0/1 或 0/255」。
  • 在主流程中,統一管理資料型態與像素值

✅ 3. 善用 assert 檢查

  • 在函式開頭加上 assert,避免型態錯誤:
    assert np.max(skeleton) in (1, 255), "骨架像素值應為 1 或 255"

4️⃣ 完整範例:兩種端點偵測都正確

# 取得骨架
skeleton_01 = skeletonize(binary_block > 0).astype(np.uint8) # 0/1
skeleton_255 = skeleton_01 * 255 # 0/255

# filter2D 法
endpoints_mask = find_skeleton_endpoints_filter2d(skeleton_01)

# for-loop 法
endpoints_loop = find_skeleton_endpoints_loop(skeleton_255)

5️⃣ 實戰小結

  • filter2D 法:只適用 0/1 圖像
  • for-loop 法:只適用 0/255 圖像
  • 型態不一致會導致偵測失敗!
  • 養成習慣:每次處理二值圖像都明確轉型、註明型態

6️⃣ 常見問答

Q:為什麼 OpenCV 有時會自動把 0/1 轉成 0/255?

A:OpenCV 的大多數函式預設處理 8-bit 圖像(0~255),但 skimage 等科學套件常用 0/1。兩者混用時,務必手動轉型。

Q:有沒有一個「萬用端點偵測」?

A:建議根據資料型態選擇方法,或在函式內自動轉型。


7️⃣ 結語

資料型態與像素值的混用,是影像處理最常見的 bug 來源之一。

每次處理二值圖像,請務必檢查型態與像素值!

這樣就能避免「端點偵測不到」這種隱藏 bug,讓你的程式更穩定、易維護!


留言
avatar-img
螃蟹_crab的沙龍
169會員
322內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。 興趣是攝影,踏青,探索未知領域。 人生就是不斷的挑戰及自我認清,希望老了躺在床上不會後悔自己什麼都沒做。
螃蟹_crab的沙龍的其他內容
2025/02/15
在電腦視覺應用中,輪廓(Contour)常用來描述物體的邊界。 當圖像中有雜訊或物體邊緣過於複雜時,我們可以利用輪廓逼近技術,將輪廓簡化成較少點數的多邊形,這不僅有助於後續的形狀分析,也能提高處理速度。 本文將介紹如何使用 OpenCV 中的 cv2.arcLength 與 cv2.approx
Thumbnail
2025/02/15
在電腦視覺應用中,輪廓(Contour)常用來描述物體的邊界。 當圖像中有雜訊或物體邊緣過於複雜時,我們可以利用輪廓逼近技術,將輪廓簡化成較少點數的多邊形,這不僅有助於後續的形狀分析,也能提高處理速度。 本文將介紹如何使用 OpenCV 中的 cv2.arcLength 與 cv2.approx
Thumbnail
2024/12/02
中值濾波器(Adaptive Median Filter)是一種針對噪聲去除的圖像處理技術,主要應用於處理含有椒鹽雜訊的圖像,但在椒鹽雜訊過大時就會面臨,若為了處理掉雜訊,使用的處理窗口(kernel)就要大一點,會造成圖像的邊緣模糊掉。 後面為解決這個問題,就發展了自適應中值濾波器,其概念源自於
Thumbnail
2024/12/02
中值濾波器(Adaptive Median Filter)是一種針對噪聲去除的圖像處理技術,主要應用於處理含有椒鹽雜訊的圖像,但在椒鹽雜訊過大時就會面臨,若為了處理掉雜訊,使用的處理窗口(kernel)就要大一點,會造成圖像的邊緣模糊掉。 後面為解決這個問題,就發展了自適應中值濾波器,其概念源自於
Thumbnail
2024/10/03
在影像處理中,形態學操作是非常重要的一種技術,能夠幫助我們去除噪點、強化特徵、修復物體的形狀等。形態學操作的核心是「結構元素」(kernel),不同形狀的結構元素會產生不同的處理效果。本文將介紹如何使用不同形狀的結構元素來進行圖像處理,並結合實際程式範例和測試圖片來說明其效果。
Thumbnail
2024/10/03
在影像處理中,形態學操作是非常重要的一種技術,能夠幫助我們去除噪點、強化特徵、修復物體的形狀等。形態學操作的核心是「結構元素」(kernel),不同形狀的結構元素會產生不同的處理效果。本文將介紹如何使用不同形狀的結構元素來進行圖像處理,並結合實際程式範例和測試圖片來說明其效果。
Thumbnail
看更多
你可能也想看
Thumbnail
瞭解二值化影像的應用和程式語法,包括物體檢測和分割、邊緣檢測、圖像分析和測量、文檔辨識,以及使用cv2.threshold的參數和程式範例。
Thumbnail
瞭解二值化影像的應用和程式語法,包括物體檢測和分割、邊緣檢測、圖像分析和測量、文檔辨識,以及使用cv2.threshold的參數和程式範例。
Thumbnail
接續上一邊,分割了螺絲與螺母的圖像,但分割後的結果,因為螺絲過於接近的關係,沒有切割乾淨,會有其他螺絲的頭或者身體,這樣會影響到後續量測。 [OpenCV應用][Python]擷取出螺絲或螺母的影像 本文主要是,如何去除掉不要的背景雜物。 下層為原先分割的圖,上層為去除背景雜物的圖。
Thumbnail
接續上一邊,分割了螺絲與螺母的圖像,但分割後的結果,因為螺絲過於接近的關係,沒有切割乾淨,會有其他螺絲的頭或者身體,這樣會影響到後續量測。 [OpenCV應用][Python]擷取出螺絲或螺母的影像 本文主要是,如何去除掉不要的背景雜物。 下層為原先分割的圖,上層為去除背景雜物的圖。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
本文將說明如何去辨識出圖片文字​位置及高寬。
Thumbnail
本文將說明如何去辨識出圖片文字​位置及高寬。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
觀看本文將可以學習到如何利用Numpy求得物件的邊緣點,及算出物件的寬跟高。 有詳細的程式邏輯說明,及各函式用法說明。 綠點及紅點則是採樣到的邊界點,比較粗的點是偵測到的最大值 完整程式碼 import cv2 import numpy as np import matplotl
Thumbnail
觀看本文將可以學習到如何利用Numpy求得物件的邊緣點,及算出物件的寬跟高。 有詳細的程式邏輯說明,及各函式用法說明。 綠點及紅點則是採樣到的邊界點,比較粗的點是偵測到的最大值 完整程式碼 import cv2 import numpy as np import matplotl
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
[OpenCV應用][Python]找出圖像中的四個方位的邊緣點求出寬高 呈上篇應用Numpy找到的座標點,那我們如何捨棄掉差異過大的座標點呢? 可能圖像物件邊緣不佳,採樣就會差異過大,造成計算出的寬高是不準確的。 遇到這種狀況,就可以使用下方的程式範例來篩選座標點。 為求方便,此範例跟圖
Thumbnail
[OpenCV應用][Python]找出圖像中的四個方位的邊緣點求出寬高 呈上篇應用Numpy找到的座標點,那我們如何捨棄掉差異過大的座標點呢? 可能圖像物件邊緣不佳,採樣就會差異過大,造成計算出的寬高是不準確的。 遇到這種狀況,就可以使用下方的程式範例來篩選座標點。 為求方便,此範例跟圖
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
在影像處理中,有時候我們只想特別關注某個感興趣的區域時,就是ROI的概念,擷取此範圍的圖像來做處理。 設定超過圖像邊界時就會報錯,本文主要介紹如何擷取影像的同時,避免設定錯誤造成程式崩潰的狀況。 擷取圖像示意圖 ROI程式範例 import cv2 import numpy as np
Thumbnail
在影像處理中,有時候我們只想特別關注某個感興趣的區域時,就是ROI的概念,擷取此範圍的圖像來做處理。 設定超過圖像邊界時就會報錯,本文主要介紹如何擷取影像的同時,避免設定錯誤造成程式崩潰的狀況。 擷取圖像示意圖 ROI程式範例 import cv2 import numpy as np
Thumbnail
在影像辨識中,若遇到物件與背景難以分辨的狀況下,先做一下色彩分析,知道了色彩強度階層上的像素數,有助於了解後續需要做什麼處理,比較好分割出辨識物。 若想辨識的物件與背景的RGB值過於接近,也比較好說明此狀況,為什麼較難分割出物件。 成果呈現 第一張圖:左邊為原圖,右邊為分析結果的圖,用其他顏
Thumbnail
在影像辨識中,若遇到物件與背景難以分辨的狀況下,先做一下色彩分析,知道了色彩強度階層上的像素數,有助於了解後續需要做什麼處理,比較好分割出辨識物。 若想辨識的物件與背景的RGB值過於接近,也比較好說明此狀況,為什麼較難分割出物件。 成果呈現 第一張圖:左邊為原圖,右邊為分析結果的圖,用其他顏
Thumbnail
此篇為上一篇文章的延伸,先辦別是螺絲還是螺母才擷取出影像。 [OpenCV應用][Python]利用findContours辨識螺絲還是螺母 因為可能會需要另外處理螺絲與螺母才可以準確地去做量測,所以第一步就是先分割出這兩種的圖像。
Thumbnail
此篇為上一篇文章的延伸,先辦別是螺絲還是螺母才擷取出影像。 [OpenCV應用][Python]利用findContours辨識螺絲還是螺母 因為可能會需要另外處理螺絲與螺母才可以準確地去做量測,所以第一步就是先分割出這兩種的圖像。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News