opencv学习(八)膨胀与腐蚀、动态调整结构元素大小

       数学形态学(Mathematical morphology) 是一门建立在格论和拓扑学基础之上的图像分析学科,是数学形态学图像处理的基本理论。其基本的运算包括:二值腐蚀和膨胀、二值开闭运算、骨架抽取、极限腐蚀、击中击不中变换、形态学梯度、Top-hat变换、颗粒分析、流域变换、灰值腐蚀和膨胀、灰值开闭运算、灰值形态学梯度等。

      在进行腐蚀和膨胀的讲解之前,首先需要注意,腐蚀和膨胀是对白色部分(高亮部分)而言的,不是黑色部分。膨胀就是图像中的高亮部分进行膨胀,“领域扩张”,效果图拥有比原图更大的高亮区域。腐蚀就是原图中的高亮部分被腐蚀,“领域被蚕食”,效果图拥有比原图更小的高亮区域。  

一、形态学操作-膨胀

       膨胀就是求局部最大值的操作。从数学方面来说,膨胀或者腐蚀操作就是将图像(或图像的一部分区域,我们称之为A)与核(我们称之为B)进行卷积。

                                                            

膨胀的数学表达式如下:

 opencv提供的API:

dilate(src,dst, InputArray kernel,Point anchor, int iterations,int borderType, constScalar& borderValue)
第三个参数:膨胀操作的核,我们一般使用getStructuringElement 配合这个参数使用
第四个参数:锚点的位置
第五个参数::迭代使用erode()函数的次数,默认值为1
使用dilate函数一般只填写前三个参数,后面四个参数使用默认值

getStructuringElement函数

getStructuringElement(shape,Size ksize,Point);
第一个参数:内核的形状 
           矩形: MORPH_RECT
           交叉形: MORPH_CROSS
           椭圆形: MORPH_ELLIPSE
第二个参数:内核的大小
第三个参数:锚点的位置

二、形态学操作—腐蚀

        膨胀和腐蚀是一对相反的操作,腐蚀是求局部最小值的操作。

                                           

腐蚀的数学表达式如下: 

opencv提供的API:

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

三、动态调整结构元素大小

 createTrackbar(const String & trackbarname, const String winName,  int* value, int count, Trackbarcallback func, void* userdata=0)

第一个参数,const string&类型的trackbarname,表示轨迹条的名字。
第二个参数,const string&类型的winname,填窗口的名字,表示这个轨迹条会依附到哪个窗口上,即对应namedWindow()创建窗口时填的某一个窗口名。
第三个参数,int* 类型的value,一个指向整型的指针,表示滑块的位置。并且在创建时,滑块的初始位置就是该变量当前的值。
第四个参数,int类型的count,表示滑块可以达到的最大位置的值。PS:滑块最小的位置的值始终为0。
第五个参数,TrackbarCallback类型的onChange,首先注意他有默认值0。这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。并且这个函数的原型必须为void XXXX(int,void*);其中第一个参数是轨迹条的位置,第二个参数是用户数据(看下面的第六个参数)。如果回调是NULL指针,表示没有回调函数的调用,仅第三个参数value有变化。
第六个参数,void*类型的userdata,他也有默认值0。这个参数是用户传给回调函数的数据,用来处理轨迹条事件。如果使用的第三个参数value实参是全局变量的话,完全可以不去管这个userdata参数。
 

完整代码:

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace std;
using namespace cv;

Mat src, dst;
int element_size = 3;
int max_size = 21;
char OUTPUT_WIN[] = "output image";
void CallBack_demo(int, void*);

int main() {
	src = imread("C:\\Users\\liuhuimin\\Desktop\\1.bmp");
	if (!src.data) {
		printf("cloud not load image");
		return -1;
	}
	imshow("原图", src);
	namedWindow(OUTPUT_WIN, CV_WINDOW_AUTOSIZE);//这一步不可以省
	createTrackbar("Element size", OUTPUT_WIN, &element_size, max_size, CallBack_demo);
	CallBack_demo(0, 0);
	waitKey(0);
	return 0;
}
	
void CallBack_demo(int, void*) {

		int s = element_size * 2 + 1;
		Mat structrueElement = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1));
		//膨胀
		//dilate(src, dst, structrueElement, Point(-1, -1), 1);
		//腐蚀
		erode(src, dst, structrueElement);
		imshow(OUTPUT_WIN, dst);
		return;
}

猜你喜欢

转载自blog.csdn.net/lhm_19960601/article/details/82560560