OpenCV笔记(八)——膨胀和腐蚀、滑动条和回调函数

一、膨胀和腐蚀

膨胀和腐蚀(Dilating and Eroding)是基本的形态学操作。在OpenCV中定义了erode和dilate函数完成相应的功能。

膨胀和腐蚀主要作用有三:去除噪声;将分离的部分邻近连接起来;将密布的像素形成一块整体。

膨胀操作也类似于线性滤波,不过使用的是最大值滤波器,以kernel范围内的最大值代替中心点。

相反地,腐蚀操作使用的是最小值滤波器。

 

下面来看看在OpenCV中如何进行膨胀和腐蚀操作:

因为erode和dilate操作可以使用定义的Kernel形状,比如常用的矩形,还有椭圆和十字可以使用。

用getStructuringElement函数定义kernel形状:

Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1, -1))

shape可以是MORPH_RECT或者MORPH_ELLIPSE或者MORPH_CROSS。

膨胀:

void dilate(InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1, -1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue())

一般我们只要关心前三个参数,dilate支持就地操作(inplace mode),所以src和dst可以相同。kernel就使用getStructuringElement()返回的Mat对象。

腐蚀:

void erode(InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1, -1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue())

使用方法和dilate()函数相同。

 

 二、滑动条(Trackbar)和回调函数(callback function)

OpenCV给我们提供了滑动条和回调函数配套的操作,如此,我们就能够实时地通过滑动条来设置变量,并调用回调函数。

int createTrackbar(const string& trackbarname, const string& winname, int* value, int count, TrackbarCallback onChange=0, void* userdata=0)

trackbarname给出滑动条的名字。

winname是滑动条要出现的窗口的名字。

value是一个已有的变量。

count是这个滑动条的最大调整范围(从0开始)。

onChange是回调函数的函数指针,这个回调函数的原型应该符合void Foo(int, void*),第一个参数传入滑动条的位置,第二个参数传入userdata。

userdata就是传入onChange的第二个参数。

举个OpenCV教学文档中使用createTrackbar的例子:

 1 int erosion_elem = 0;
 2 int erosion_size = 0;
 3 int const max_elem = 2;
 4 int const max_kernel_size = 21;
 5 
 6 createTrackbar( "Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Erosion Demo",
 7           &erosion_elem, max_elem,
 8           Erosion );
 9 
10 createTrackbar( "Kernel size:\n 2n +1", "Erosion Demo",
11           &erosion_size, max_kernel_size,
12           Erosion );
13 
14 void Erosion( int, void* )
15 {
16   int erosion_type = 0;
17   if( erosion_elem == 0 ){ erosion_type = MORPH_RECT; }
18   else if( erosion_elem == 1 ){ erosion_type = MORPH_CROSS; }
19   else if( erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }
20 
21   Mat element = getStructuringElement( erosion_type,
22                        Size( 2*erosion_size + 1, 2*erosion_size+1 ),
23                        Point( erosion_size, erosion_size ) );
24   /// Apply the erosion operation
25   erode( src, erosion_dst, element );
26   imshow( "Erosion Demo", erosion_dst );
27 }

 

第6行和第10行,为Erosion Demo窗口设置了两个滑动条,并为这两个滑动条设置了名字、参数、参数可调整的范围、回调函数。这里回调函数并未使用userdata参数。

我们看第14行,Erode就是回调函数,它符合void Foo(int, void*)的函数原型。(原型是ANSI C的说法,原型定义了一个函数的名字、返回值和形参个数、类型。)

一般来说,在设置滑动条、定义回调函数之后,我们利用Erode(0, 0)来做Default start。

 

 

讲的比较简单,见谅。

 

posted @ 2014-11-26 22:12  nipan  阅读(1451)  评论(0编辑  收藏  举报