形态学操作是基于形状的一系列图像处理操作,基本的运算包括:腐蚀、膨胀、开、闭等。在进行其他算法研发时,我基本只用膨胀与腐蚀操作,因此本文只介绍这两种操作,其他的可以相似地进行。
为了更加清晰地显示出操作前后的差距,采用如下图所示的二值图
一定要注意,形态学操作不光可以用在二值图,也可以用在灰度图,甚至可以用在彩色图。
以下代码是OpenCV文档中给出的一段代码,比较能说明问题,我加了一些注释
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "highgui.h"
#include
#include
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()
{
/// Load an image
src = imread("coins.png");
if( !src.data )
{
return -1;
}
/// Create windows
namedWindow( "Erosion Demo", CV_WINDOW_AUTOSIZE );
namedWindow( "Dilation Demo", CV_WINDOW_AUTOSIZE );
//Element:\n 0: Rect \n 1: Cross \n 2: Ellipse
/// 腐蚀操作滚动条
createTrackbar( "Element:", "Erosion Demo",&erosion_elem, max_elem,Erosion );
createTrackbar( "Kernel", "Erosion Demo",&erosion_size, max_kernel_size,Erosion );
/// 膨胀操作滚动条
createTrackbar( "Element:", "Dilation Demo",&dilation_elem, max_elem,Dilation );
createTrackbar( "Kernel", "Dilation Demo",&dilation_size, max_kernel_size,Dilation );
// 开始
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 );
}
可以看出,当白色区域为圆形时,采用椭圆形的结构元素生成的结果较为规则,圆形结构保持较为完整。