opencv 筆記10 Imgproc_Morphology

膨脹和腐蝕
膨脹就是使用算法,將圖像的邊緣擴大些。作用就是將目標的邊緣或者是內部的坑填掉。 腐蝕就是使用算法,將圖像的邊緣腐蝕掉。作用就是將目標的邊緣的“毛刺”踢除掉。 使用相同次數的腐蝕與膨脹,可以使目標表面更平滑。
若先腐蝕後膨脹的過程:利用它可以消除小物體,在纖細點處分離物體,平滑較大物體邊界,但同時並不會明顯改變原來物體的面積。而先膨脹後腐蝕的過程:利用它可以填充物體內細小空洞,連接臨近物體、平滑其邊界,但同時並不會明顯改變原來物體的面積。
通常由於噪聲的影響,圖像在閾值化後所得到的邊界通常都很不平滑,物體區域具有一些噪聲孔,而背景區域上散佈着一些小的噪聲物體,連續的開和閉運算可以有效的改善這種情況,而有時,我們需要經過多次腐蝕之,後再加上相同次數的膨脹,才能產生比較好的處理效果。可見圖像腐蝕與圖像膨脹相結合有時可使圖像有較理想的處理效果。
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "highgui.h"
#include <stdlib.h>
#include <stdio.h>

using namespace cv;

/// 全局變量
Mat src, erosion_dst, dilation_dst;

int erosion_elem = 0;
int erosion_size = 0;
int dilation_elem = 0;
int dilation_size = 0;
int const max_elem = 2;
int const max_kernel_size = 21;

/** Function Headers */
void Erosion( int, void* );
void Dilation( int, void* );

/** @function main */
int main( int argc, char** argv )
{
  /// Load 圖像
  src = imread( argv[1] );

  if( !src.data )
  { return -1; }

  /// 創建顯示窗口
  namedWindow( "Erosion Demo", CV_WINDOW_AUTOSIZE );
  namedWindow( "Dilation Demo", CV_WINDOW_AUTOSIZE );
  cvMoveWindow( "Dilation Demo", src.cols, 0 );

  /// 創建腐蝕 Trackbar
  createTrackbar( "Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Erosion Demo",
                  &erosion_elem, max_elem,
                  Erosion );

  createTrackbar( "Kernel size:\n 2n +1", "Erosion Demo",
                  &erosion_size, max_kernel_size,
                  Erosion );

  /// 創建膨脹 Trackbar
  createTrackbar( "Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Dilation Demo",
                  &dilation_elem, max_elem,
                  Dilation );

  createTrackbar( "Kernel size:\n 2n +1", "Dilation Demo",
                  &dilation_size, max_kernel_size,
                  Dilation );

  /// Default start
  Erosion( 0, 0 );
  Dilation( 0, 0 );

  waitKey(0);
  return 0;
}

/**  @function Erosion  */
void Erosion( int, void* )
{
  int erosion_type;
  if( erosion_elem == 0 ){ erosion_type = MORPH_RECT; }
  else if( erosion_elem == 1 ){ erosion_type = MORPH_CROSS; }
  else if( erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }

  Mat element = getStructuringElement( erosion_type,
                                       Size( 2*erosion_size + 1, 2*erosion_size+1 ),
                                       Point( erosion_size, erosion_size ) );

  /// 腐蝕操作
  erode( src, erosion_dst, element );
  imshow( "Erosion Demo", erosion_dst );
}

/** @function Dilation */
void Dilation( int, void* )
{
  int dilation_type;
  if( dilation_elem == 0 ){ dilation_type = MORPH_RECT; }
  else if( dilation_elem == 1 ){ dilation_type = MORPH_CROSS; }
  else if( dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; }

  Mat element = getStructuringElement( dilation_type,
                                       Size( 2*dilation_size + 1, 2*dilation_size+1 ),
                                       Point( dilation_size, dilation_size ) );
  ///膨脹操作
  dilate( src, dilation_dst, element );
  imshow( "Dilation Demo", dilation_dst );
}
void erodeconst Mat& srcMat& dst, const Mat& element, Point anchor=Point(-1, -1), int iterations=1, intborderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue()
Parameters:
  • src – The source image
  • dst – The destination image. It will have the same size and the same type as src
  • element – The structuring element used for dilation. If element=Mat() , a 3\times 3 rectangular structuring element is used
  • anchor – Position of the anchor within the element. The default value (-1, -1) means that the anchor is at the element center
  • iterations – The number of times erosion is applied
  • borderType – The pixel extrapolation method; see borderInterpolate()
  • borderValue – The border value in case of a constant border. The default value has a special meaning, seecreateMorphoogyFilter()
\texttt{dst} (x,y) =  \min _{(x',y'):  \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')
Mat getStructuringElementint shape, Size esize, Point anchor=Point(-1, -1)
Parameters:
  • shape – The element shape, one of:
  • MORPH_RECT - rectangular structuring element

    E_{ij}=1

  • MORPH_ELLIPSE - elliptic structuring element, i.e. a filled ellipse inscribed into the rectangle

    Rect(0, 0, esize.width, 0.esize.height)

  • MORPH_CROSS - cross-shaped structuring element:

    E_{ij} =  \fork{1}{if i=\texttt{anchor.y} or j=\texttt{anchor.x}}{0}{otherwise}

Parameters:                          
  • esize – Size of the structuring element
  • anchor – The anchor position within the element. The default value (-1, -1) means that the anchor is at the center. Note that only the cross-shaped element’s shape depends on the anchor position; in other cases the anchor just regulates by how much the result of the morphological operation is shifted
Parameters:                                 
  • trackbarname – Name of the created trackbar.
  • winname – Name of the window which will be used as a parent of the created trackbar.
  • value – The optional pointer to an integer variable, whose value will reflect the position of the slider. Upon creation, the slider position is defined by this variable.
  • count – The maximal position of the slider. The minimal position is always 0.
  • onChange – Pointer to the function to be called every time the slider changes position. This function should be prototyped as void Foo(int,void*); , where the first parameter is the trackbar position and the second parameter is the user data (see the next parameter). If the callback is NULL pointer, then no callbacks is called, but only value is updated
  • userdata – The user data that is passed as-is to the callback; it can be used to handle trackbar events without using global variables
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章