《OpenCV3编程入门》学习笔记6 图像处理(三)形态学滤波(1):腐蚀与膨胀

第6章 图像处理

6.3 形态学滤波(1):腐蚀与膨胀

6.3.1 形态学概述

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

6.3.2 膨胀

1.求局部最大值的操作,数学角度:将图像与核进行卷积,即计算核覆盖区域的像素点最大值,并把最大值赋值给参考点指定像素,这样就会使图像中高亮区域逐渐增长。
2.核:带有一个参考点(锚点,anchor point),任意形状大小的区域。
3.膨胀数学表达式
          《OpenCV3编程入门》学习笔记6 图像处理(三)形态学滤波(1):腐蚀与膨胀
          《OpenCV3编程入门》学习笔记6 图像处理(三)形态学滤波(1):腐蚀与膨胀
4.封装函数:dilate函数
5.函数原型

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

6.参数说明
(1)输入图像
(2)目标图像
(3)膨胀操作的核,为NULL时表示使用参考点位于中心3*3的核,常使用getStructuringElement返回指定形状和大小的结构元素
    1)形状:矩型:MORPH_RECT,交叉型:MORPH_CROSS,椭圆形:MORPH_ELLIPSE
    2)内核尺寸
    3)锚点位置
    4)调用示例:

Int g_nStructElementSize = 3;
Mat element = getStructuringElement(MORPH_RECT, Size(2*g_nStructuringElement+1, 2*g_nStructElementSize+1), Point(g_nStructElementSize,g_nStructElementSize ));

(4)锚的位置,默认(-1,-1)表示位于中心
(5)迭代使用dilate()函数的次数,默认1
(6)用于推断图像外部像素的某种边界模式,默认值BORDER_DFALUT
(7)当边界为常数时的边界值,默认值morphologyDefalutBorderValue()

6.3.3 腐蚀

1.求局部最小值的操作,将图像与核进行卷积,即计算核覆盖区域的像素点最小值,并赋值给参考点指定的像素,这样就会使图像中高亮区域逐渐增长。
2.腐蚀的数学表达式
          《OpenCV3编程入门》学习笔记6 图像处理(三)形态学滤波(1):腐蚀与膨胀
          《OpenCV3编程入门》学习笔记6 图像处理(三)形态学滤波(1):腐蚀与膨胀

3.封装函数:erode()函数
4.函数原型

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

5.参数说明
(1)输入图像
(2)目标图像
(3)腐蚀操作的核,为NULL时表示使用参考点位于中心3*3的核,常使用getStructuringElement返回指定形状和大小的结构元素
(4)锚的位置,默认(-1,-1)表示位于中心
(5)迭代使用erode()函数的次数,默认1
(6)用于推断图像外部像素的某种边界模式,默认值BORDER_DFALUT
(7)当边界为常数时的边界值,默认值morphologyDefalutBorderValue()

6.3.4 综合示例:腐蚀与膨胀

//滑动条1用于腐蚀与膨胀之间切换
//滑动条2用于调节内核尺寸
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;

//全局变量
Mat g_srcImage, g_dstImage;
int g_nTrackbarNumber = 0;//0表示腐蚀erode,1表示膨胀dilate
int g_nStructElementSize = 3;//结构元素(内核矩阵)的尺寸

//全局函数
void Process(); //膨胀和腐蚀的处理函数
void on_TrackbarNumChange(int, void*);//腐蚀和膨胀操作之间切换开关的回调函数
void on_ElementSizeChange(int, void*);//腐蚀和膨胀操作内核改变时的回调函数

int main()
{
	//改变console颜色
	system("color 5E");

	//载入原图
	g_srcImage = imread("love.jpg");
	if (!g_srcImage.data)
	{
		printf("载入源图像错误~!\n");
		return false;
	}
	//显示原图
	namedWindow("【原始图】");
	imshow("【原始图】", g_srcImage);

	//创建效果图窗口
	namedWindow("【效果图】");
	//创建轨迹条
	createTrackbar("腐蚀/膨胀", "【效果图】", &g_nTrackbarNumber, 1, on_TrackbarNumChange);
	createTrackbar("内核尺寸", "【效果图】", &g_nStructElementSize, 21, on_ElementSizeChange);
	on_TrackbarNumChange(g_nTrackbarNumber, 0);

	waitKey(0);
	return 0;
}
//进行自定义的腐蚀和膨胀操作
void Process()
{
	//获取自定义核
	Mat element = getStructuringElement(MORPH_RECT, Size(2 * g_nStructElementSize + 1, 2 * g_nStructElementSize + 1), Point(g_nStructElementSize, g_nStructElementSize));
	//进行腐蚀或膨胀操作
	if (g_nTrackbarNumber == 0)
	{
		erode(g_srcImage, g_dstImage, element);
	}
	else
	{
		dilate(g_srcImage, g_dstImage, element);
	}
	//显示效果图
	imshow("【效果图】", g_dstImage);
}
//腐蚀和膨胀操作之间切换开关的回调函数
void on_TrackbarNumChange(int, void*)
{
	//腐蚀和膨胀之间效果已经切换,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来
	Process();
}
//腐蚀和膨胀操作内核改变时的回调函数
void on_ElementSizeChange(int, void*)
{
	//内核尺寸已改变,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来
	Process();
}

运行效果:

《OpenCV3编程入门》学习笔记6 图像处理(三)形态学滤波(1):腐蚀与膨胀

《OpenCV3编程入门》学习笔记6 图像处理(三)形态学滤波(1):腐蚀与膨胀
《OpenCV3编程入门》学习笔记6 图像处理(三)形态学滤波(1):腐蚀与膨胀