OpenCV 4.12.0
開源計算機視覺
載入中...
搜尋中...
無匹配項
更多形態學變換

上一教程: 腐蝕與膨脹
下一教程: 擊中或擊不中

原始作者Ana Huamán
相容性OpenCV >= 3.0

目標

在本教程中,您將學習如何

  • 使用OpenCV函式 cv::morphologyEx 應用形態學轉換,例如
    • 開運算
    • 閉運算
    • 形態學梯度
    • 頂帽
    • 黑帽

理論

注意
以下解釋摘自Bradski和Kaehler的著作《Learning OpenCV》。

在上一教程中,我們介紹了兩個基本的形態學操作

  • 腐蝕
  • 膨脹。

基於這兩個操作,我們可以對影像進行更復雜的轉換。這裡我們簡要討論OpenCV提供的5種操作

開運算

  • 開運算是透過對影像進行腐蝕後,再進行膨脹得到的。

    \[dst = open( src, element) = dilate( erode( src, element ) )\]

  • 用於移除小物體(假設物體在暗背景上是亮的)
  • 例如,請看下面的示例。左側影像是原始影像,右側影像是應用開運算轉換後的結果。我們可以觀察到小點已經消失了。

閉運算

  • 閉運算是透過對影像進行膨脹後,再進行腐蝕得到的。

    \[dst = close( src, element ) = erode( dilate( src, element ) )\]

  • 用於移除小孔(暗區域)。

形態學梯度

  • 它是影像膨脹與腐蝕之間的差異。

    \[dst = morph_{grad}( src, element ) = dilate( src, element ) - erode( src, element )\]

  • 它有助於找到物體的輪廓,如下所示

頂帽

  • 它是輸入影像與其開運算之間的差異。

    \[dst = tophat( src, element ) = src - open( src, element )\]

黑帽

  • 它是閉運算與其輸入影像之間的差異

    \[dst = blackhat( src, element ) = close( src, element ) - src\]

程式碼

解釋

  1. 讓我們看看C++程式的總體結構
    • 載入影像
    • 建立一個視窗來顯示形態學操作的結果
    • 建立三個滑動條供使用者輸入引數
      • 第一個滑動條Operator返回要使用的形態學操作型別(morph_operator)。
        createTrackbar("運算子:\n 0: 開運算 - 1: 閉運算 \n 2: 梯度 - 3: 頂帽 \n 4: 黑帽", window_name, &morph_operator, max_operator, Morphology_Operations );
      • 第二個滑動條Element返回morph_elem,它指示我們的核是什麼型別的結構
        createTrackbar( "元素:\n 0: 矩形 - 1: 十字形 - 2: 橢圓形 - 3: 菱形", window_name,
        &morph_elem, max_elem,
        Morphology_Operations );
      • 最後一個滑動條Kernel Size返回要使用的核的大小(morph_size
        createTrackbar( "核大小:\n 2n +1", window_name,
        &morph_size, max_kernel_size,
        Morphology_Operations );
    • 每次我們移動任何滑動條時,都會呼叫使用者函式Morphology_Operations來執行新的形態學操作,並根據當前的滑動條值更新輸出影像。

      void Morphology_Operations( int, void* )
      {
      // 由於 MORPH_X : 2,3,4,5 和 6
      int operation = morph_operator + 2;
      Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );
      morphologyEx( src, dst, operation, element );
      imshow( window_name, dst );
      }

      我們可以觀察到執行形態學轉換的關鍵函式是 cv::morphologyEx 。在這個例子中,我們使用了四個引數(其餘使用預設值)

      • src : 源(輸入)影像
      • dst: 輸出影像
      • operation: 要執行的形態學轉換型別。請注意,我們有5種選擇

        • 開運算: MORPH_OPEN : 2
        • 閉運算: MORPH_CLOSE: 3
        • 梯度: MORPH_GRADIENT: 4
        • 頂帽: MORPH_TOPHAT: 5
        • 黑帽: MORPH_BLACKHAT: 6

        如您所見,這些值的範圍是<2-6>,這就是為什麼我們將滑動條輸入的值加(+2)。

        int operation = morph_operator + 2;
      • element: 要使用的核。我們使用函式 cv::getStructuringElement 來定義我們自己的結構。

結果

  • 編譯上述程式碼後,我們可以透過提供影像路徑作為引數來執行它。使用影像 baboon.png 的結果:
  • 這裡是顯示視窗的兩個截圖。第一張圖片顯示了使用開運算運算子和十字形核的結果。第二張圖片(右側)顯示了使用黑帽運算子和橢圓形核的結果。