膨脹和腐蝕
膨脹就是使用算法,將圖像的邊緣擴大些。作用就是將目標的邊緣或者是內部的坑填掉。 腐蝕就是使用算法,將圖像的邊緣腐蝕掉。作用就是將目標的邊緣的“毛刺”踢除掉。 使用相同次數的腐蝕與膨脹,可以使目標表面更平滑。
若先腐蝕後膨脹的過程:利用它可以消除小物體,在纖細點處分離物體,平滑較大物體邊界,但同時並不會明顯改變原來物體的面積。而先膨脹後腐蝕的過程:利用它可以填充物體內細小空洞,連接臨近物體、平滑其邊界,但同時並不會明顯改變原來物體的面積。
通常由於噪聲的影響,圖像在閾值化後所得到的邊界通常都很不平滑,物體區域具有一些噪聲孔,而背景區域上散佈着一些小的噪聲物體,連續的開和閉運算可以有效的改善這種情況,而有時,我們需要經過多次腐蝕之,後再加上相同次數的膨脹,才能產生比較好的處理效果。可見圖像腐蝕與圖像膨脹相結合有時可使圖像有較理想的處理效果。
#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& src, Mat& dst, const Mat& element, Point anchor=Point(-1, -1), int iterations=1, intborderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue()
Parameters: |
|
---|
Mat getStructuringElementint shape, Size esize, Point anchor=Point(-1, -1)
Parameters: |
|
---|
MORPH_RECT - rectangular structuring element
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:
Parameters: |
|
---|
Parameters: |
|
---|