一、概述
返回指定大小和形状的结构元素,用于形态学操作。该函数构造并返回可以进一步传递给 erode、dilate 或morphologyEx 的结构元素。 但是您也可以自己构建任意二值mask并将其用作结构元素。
结构元素是一个小的二进制图像,即一个小的像素矩阵,每个像素的值为零或一:
- 矩阵维度指定结构元素的大小。
- 1 和 0 的模式指定了结构元素的形状。
- 结构元素的原点通常是其像素之一,尽管通常原点可以在结构元素之外。
某些情况下,您可能需要椭圆形/圆形的内核。 所以为了这个目的。 您只需传递内核的形状和大小,即可获得所需的内核。
cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
比如使用上面的代码可以得到,如下的结构元素。矩形,椭圆、十字形状。
二、getStructuringElement函数
1、函数原型
cv::getStructuringElement (int shape, Size ksize, Point anchor=Point(-1,-1))
2、参数详解
shape | 可能是 MorphShapes 之一的元素形状,矩形、十字、椭圆 |
ksize | 结构元素的大小。 |
anchor | 元素内的锚点位置。 默认值 (-1,-1) 表示锚点位于中心。 请注意,只有十字形元素的形状取决于锚点位置。 在其他情况下,anchor 只是调节形态操作的结果移动了多少。 |
三、OpenCV源码
1、源码路径
opencv\modules\imgproc\src\morph.dispatch.cpp
2、源码代码
Mat getStructuringElement(int shape, Size ksize, Point anchor)
{
int i, j;
int r = 0, c = 0;
double inv_r2 = 0;
CV_Assert( shape == MORPH_RECT || shape == MORPH_CROSS || shape == MORPH_ELLIPSE );
anchor = normalizeAnchor(anchor, ksize);
if( ksize == Size(1,1) )
shape = MORPH_RECT;
if( shape == MORPH_ELLIPSE )
{
r = ksize.height/2;
c = ksize.width/2;
inv_r2 = r ? 1./((double)r*r) : 0;
}
Mat elem(ksize, CV_8U);
for( i = 0; i < ksize.height; i++ )
{
uchar* ptr = elem.ptr(i);
int j1 = 0, j2 = 0;
if( shape == MORPH_RECT || (shape == MORPH_CROSS && i == anchor.y) )
j2 = ksize.width;
else if( shape == MORPH_CROSS )
j1 = anchor.x, j2 = j1 + 1;
else
{
int dy = i - r;
if( std::abs(dy) <= r )
{
int dx = saturate_cast<int>(c*std::sqrt((r*r - dy*dy)*inv_r2));
j1 = std::max( c - dx, 0 );
j2 = std::min( c + dx + 1, ksize.width );
}
}
for( j = 0; j < j1; j++ )
ptr[j] = 0;
for( ; j < j2; j++ )
ptr[j] = 1;
for( ; j < ksize.width; j++ )
ptr[j] = 0;
}
return elem;
}
四、效果图像示例
以下代码摘自官方文档,介绍了结构元素在腐蚀、膨胀中的使用。
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
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;
void Erosion( int, void* );
void Dilation( int, void* );
int main( int argc, char** argv )
{
CommandLineParser parser( argc, argv, "{@input | LinuxLogo.jpg | input image}" );
src = imread( samples::findFile( parser.get<String>( "@input" ) ), IMREAD_COLOR );
if( src.empty() )
{
cout << "Could not open or find the image!\n" << endl;
cout << "Usage: " << argv[0] << " <Input image>" << endl;
return -1;
}
namedWindow( "Erosion Demo", WINDOW_AUTOSIZE );
namedWindow( "Dilation Demo", WINDOW_AUTOSIZE );
moveWindow( "Dilation Demo", src.cols, 0 );
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 );
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 );
Erosion( 0, 0 );
Dilation( 0, 0 );
waitKey(0);
return 0;
}
void Erosion( int, void* )
{
int erosion_type = 0;
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 );
}
void Dilation( int, void* )
{
int dilation_type = 0;
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 );
}
![](https://img-blog.csdnimg.cn/bfe9b9ebbe2d4693b3cf934ec9150775.jpeg)
![](https://img-blog.csdnimg.cn/1cae0cb785834eac850a8a28dcf6efef.jpeg)