OpenCV 形狀分析(上):計算輪廓中心

NoneLand發表於2016-07-07

5

今天,我們將開始由3部分構成的形狀檢測分析系列教程。

通過此係列教程,我們將學到如何:

  1. 計算輪廓/形狀的中心;
  2. 僅使用輪廓特徵識別出不同的形狀,如:圓、正方形、長方形、三角形和五角形。
  3. 標記形狀顏色

儘管今天的內容比較基礎(相對於最近 PyImageSearch 部落格討論的更加高階的概念來說),但是也經常有人問我下邊這個問題:

如何用 Python 和 OpenCV 計算輪廓的中心?

在今天的教程中,我將會回答這個問題。

在以後的教程中,我們將在輪廓知識的基礎上進行影像的形狀識別。

使用 OpenCV 計算輪廓中心

包含不同形狀的待計算輪廓中心的示例圖

圖1:包含不同形狀的待計算輪廓中心的示例影像

從上圖中,你能看見幾種不同的由圖畫紙裁出的形狀。注意,這些形狀並不完美——矩形不夠方,圓形不夠圓。它們都是先經手工描畫然後再裁出來的,這意味著每種形狀都存在著偏差。

明確了這一點之後,今天教程的目標是:(1)檢測出影像中的每一種形狀的輪廓(2)計算輪廓的中心——也叫形心。

為了達成以上目標,我們需要對影像進行以下預處理:

  • 轉換成灰度圖;
  • 濾波以減少高頻噪聲,使輪廓檢測更加精確;
  • 影像二值化。邊緣檢測和閾值化經常被用於此過程,本教程採用閾值化。

開始寫程式碼之前,請確保你的系統已經安裝了 imutils Python 包[ 譯註:該包為作者開發的一系列用 OpenCV 執行基本影像處理操作的簡便函式]。

讓我們繼續!

新建一個檔案,命名為 center_of_shape.py,然後開始寫程式碼吧:

第2-4行程式碼匯入必需的包,第7-10行程式碼解析命令列引數。此處只需要一個 --image 引數: 磁碟中待處理影像的路徑。

隨後程式從磁碟載入影像,然後進行預處理,執行灰度變換,5×5 核心的高斯平滑,最後閾值化(14-17行)。

閾值化操作後的輸出如下圖所示

圖2:閾值化影像操作返回二值影像,其中形狀被表示為黑色背景上的白塊

圖2:影像閾值化返回二值影像,其中形狀被表示為黑色背景上的白塊

注意閾值化後形狀被表示成黑色背景上的白色前景。

下一步是使用輪廓檢測去定位這些白色區域。

第 20-21 行程式碼呼叫 cv2.findContours 函式,該函式返回影像上每一個白塊對應的邊界點集合(即輪廓)。第22行基於我們使用 OpenCV 2.4 版本還是3.0 版本而取不同的元組值。獲取更多 cv2.findContours 函式返回簽名在不同 OpenCV 版本間的改變,請移步此文。[譯註:OpenCV 2.4 版本的 cv2.findContours 函式返回的是一個二元元組,元組的第一個元素(索引 0)是輪廓列表。而在 OpenCV 3.0 版本中,該函式返回的是一個三元元組,元組的第二個元素(索引 1)才是輪廓列表]

我們已經準備去處理每一條輪廓:

第25行開始遍歷輪廓,然後在第27行計算輪廓區域影像的矩

在計算機視覺和影像處理領域,影像的矩經常被用來描述影像中某個物件的形狀。這些矩描述了形狀的基本統計特徵,包括物件的面積、形心(即物件的中心座標 (x, y))、取向連同其他有用的特徵。

我們只對影像的中心感興趣,所以在第28-29行計算輪廓的中心。

隨後,第32-34行完成以下任務:

  • 呼叫 cv2.drawContours 函式繪製包圍當前形狀的輪廓;
  • 在形狀的中心 (cX, cY) 處繪製一個白色的小圓;
  • 在白色小圓的附近寫上文字 center

要執行指令碼,開啟終端然後執行以下命令:

執行結果如下圖所示:

圖3:

圖3:分別遍歷每一個形狀並計算每一個形狀的中心 (x, y)。(點選圖片有驚醒)

注意每一個形狀都被成功地檢測到,然後計算出輪廓中心並繪製在影像上。

總結

在這次教程中,我們學習瞭如何使用 OpenCV 和 Python 去計算輪廓的中心。

此教程是由三部分構成的形狀分析系列教程的第一部分。

在下週的教程中,我們將學習如何識別影像中的形狀

然後,在兩週以後,我們將學習如何分析每一個形狀的顏色並將其標記在形狀上(即標記“紅”、“綠”、“藍”等等)。

為了確保這些教程寫成的時候您能被通知到,請按照以下形式輸入您的郵箱地址![譯註:原部落格提供程式碼下載和郵件提醒功能。戳我訪問原文。]

相關文章