OpenCV形态学之膨胀腐蚀

知识共享许可协议 版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons


一、获得核getStructuringElement()

原型

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

参数

  • shape:形状

    • MORPH_RECT :矩形
    • MORPH_CROSS :交叉形
    • MORPH_ELLIPSE :椭圆形
  • ksize:结构元素的大小。其两个元素都不能小于1。

  • anchor:锚的位置。默认(-1,-1),表示锚位于中心。

如:

Mat kernel=getStrucutringElement(MORPH_RECT,Size(15,15));

二、膨胀dilate()和腐蚀erode()

1.膨胀dilate()

原型

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

参数

  • src:输入图像
  • dst:输出图像
  • kernel:膨胀操作的核,也是Mat类。用getStructuringElement()获得的Mat对象
  • anchor:锚的位置。默认(-1,-1),表示锚位于中心
  • iterations:迭代使用erode()的次数。默认1次
  • borderType:用于推断图像外部像素的某种边界模式。
  • borderValue:不管

例子

#include<opencv2/opencv.hpp>
using namespace cv;

int main()
{
	Mat srcImage=imread("3.jpg");
	imshow("srcImage",srcImage);
	Mat kernel=getStructuringElement(MORPH_RECT,Size(15,15));
	Mat dstImage;
	dilate(srcImage,dstImage,kernel);
	imshow("Effect",dstImage);
	waitKey();
	return 0;
}

在这里插入图片描述

2.腐蚀erode()

原型

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

参数

  • src:输入图像
  • dst:输出图像
  • kernel:膨胀操作的核,也是Mat类。用getStructuringElement()获得的Mat对象
  • anchor:锚的位置。默认(-1,-1),表示锚位于中心
  • iterations:迭代使用erode()的次数。默认1次
  • borderType:用于推断图像外部像素的某种边界模式。
  • borderValue:不管

例子

#include<opencv2/opencv.hpp>
using namespace cv;

int main()
{
	Mat srcImage=imread("3.jpg");
	imshow("srcImage",srcImage);
	Mat kernel=getStructuringElement(MORPH_RECT,Size(15,15));
	Mat dstImage;
	erode(srcImage,dstImage,kernel);
	imshow("Effect",dstImage);
	waitKey();
	return 0;
}

在这里插入图片描述

三、复杂形态学运算

1.形态学梯度Gradient

形态学梯度=膨胀-腐蚀
dst=morph=grad(src,element)=dilate(src,element)-erode(src,element)

2.开运算和闭运算

关系

  • 开运算=先腐蚀后膨胀
    dst=open(src,element)=dilate(erode(src,element))
  • 闭运算=先膨胀后腐蚀
    dst=clese(src,element)=erode(dilate(src,element))

3.顶帽和黑帽

关系

  • 顶帽=原图-开运算
    dst=tophat(src,element)=src-open(src,element)
  • 黑帽=闭运算-原图
    dst=blackhat(src,element)=close(src,element)-src

四、集成函数morphologyEx()

原型

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

参数

  • src:输入图像

  • dst:输出图像

  • op:表示形态学运算类型

    • MORPH_DILATE:膨胀
    • MORPH_ ERODE:腐蚀
    • MORPH_OPEN:开运算
    • MORPH_CLOSE:闭运算
    • MORPH_GRADIENT:形态学梯度
    • MORPH_TOPHAT:顶帽
    • MORPH_BLACKHAT:黑帽
  • kernel:膨胀操作的核,也是用getStructuringElement()获得的Mat对象。其两个元素都不能小于1。

  • anchor:锚的位置。默认(-1,-1),表示锚位于中心

  • iterations:迭代使用erode()的次数。默认1次

  • borderType:用于推断图像外部像素的某种边界模式。

  • borderValue:不管

例子:开运算

Mat kernel=getStructuringElement(MORPH_RECT,Size(15,15));
morphologyEx(srcImage,dstImage,MORPH_OPEN,kernel);

五、滑动条调试核的Size

1.代码

滑动条的数值大小value就是kernel的Size(value,value)

#include<opencv2/opencv.hpp>
using namespace cv;

Mat g_srcImage;

Mat g_dstDILATEImage;
Mat g_dstERODEImage;
Mat g_dstOPENImage;
Mat g_dstCLOSEImage;
Mat g_dstGRADIENTImage;
Mat g_dstTOPHATImage;
Mat g_dstBLACKHATImage;


int g_DILATEValue=1;
int g_ERODEValue=1;
int g_OPENValue=1;
int g_CLOSEValue=1;
int g_GRADIENTValue=1;
int g_TOPHATValue=1;
int g_BLACKHATValue=1;

const int MaxValue=200;

void onChange_DILATE(int,void*)
{
	if(g_DILATEValue<=1) g_DILATEValue=1;
	Mat kernel=getStructuringElement(MORPH_RECT,Size(g_DILATEValue,g_DILATEValue));
	morphologyEx(g_srcImage,g_dstDILATEImage,MORPH_DILATE,kernel);
	imshow("DILATEWindow",g_dstDILATEImage);
}

void onChange_ERODE(int,void*)
{
	if(g_ERODEValue<=1) g_ERODEValue=1;
	Mat kernel=getStructuringElement(MORPH_RECT,Size(g_ERODEValue,g_ERODEValue));
	morphologyEx(g_srcImage,g_dstERODEImage,MORPH_ERODE,kernel);
	imshow("ERODEWindow",g_dstERODEImage);
}

void onChange_OPEN(int,void*)
{
	if(g_OPENValue<=1) g_OPENValue=1;
	Mat kernel=getStructuringElement(MORPH_RECT,Size(g_OPENValue,g_OPENValue));
	morphologyEx(g_srcImage,g_dstOPENImage,MORPH_OPEN,kernel);
	imshow("OPENWindow",g_dstOPENImage);
}

void onChange_CLOSE(int,void*)
{
	if(g_CLOSEValue<=1) g_CLOSEValue=1;
	Mat kernel=getStructuringElement(MORPH_RECT,Size(g_CLOSEValue,g_CLOSEValue));
	morphologyEx(g_srcImage,g_dstCLOSEImage,MORPH_CLOSE,kernel);
	imshow("CLOSEWindow",g_dstCLOSEImage);
}

void onChange_GRADIENT(int,void*)
{
	if(g_GRADIENTValue<=1) g_GRADIENTValue=1;
	Mat kernel=getStructuringElement(MORPH_RECT,Size(g_GRADIENTValue,g_GRADIENTValue));
	morphologyEx(g_srcImage,g_dstGRADIENTImage,MORPH_GRADIENT,kernel);
	imshow("GRADIENTWindow",g_dstGRADIENTImage);
}

void onChange_TOPHAT(int,void*)
{
	if(g_TOPHATValue<=1) g_TOPHATValue=1;
	Mat kernel=getStructuringElement(MORPH_RECT,Size(g_TOPHATValue,g_TOPHATValue));
	morphologyEx(g_srcImage,g_dstTOPHATImage,MORPH_TOPHAT,kernel);
	imshow("TOPHATWindow",g_dstTOPHATImage);
}

void onChange_BLACKHAT(int,void*)
{
	if(g_BLACKHATValue<=1) g_BLACKHATValue=1;
	Mat kernel=getStructuringElement(MORPH_RECT,Size(g_BLACKHATValue,g_BLACKHATValue));
	morphologyEx(g_srcImage,g_dstBLACKHATImage,MORPH_BLACKHAT,kernel);
	imshow("BLACKHATWindow",g_dstBLACKHATImage);
}

int main()
{
	g_srcImage=imread("M569_989_066.jpg");
	//resize(g_srcImage,g_srcImage,Size(),0.3,0.3,INTER_AREA);
	//调整原图像大小
	imshow("srcImage",g_srcImage);
	
	namedWindow("DILATEWindow",WINDOW_NORMAL);
	createTrackbar("DILATE","DILATEWindow",&g_DILATEValue,MaxValue,onChange_DILATE);
	onChange_DILATE(0,0);

	namedWindow("ERODEWindow",WINDOW_NORMAL);
	createTrackbar("ERODE","ERODEWindow",&g_ERODEValue,MaxValue,onChange_ERODE);
	onChange_ERODE(0,0);
	
	namedWindow("OPENWindow",WINDOW_NORMAL);
	createTrackbar("OPEN","OPENWindow",&g_OPENValue,MaxValue,onChange_OPEN);
	onChange_OPEN(0,0);
	
	namedWindow("CLOSEWindow",WINDOW_NORMAL);
	createTrackbar("CLOSE","CLOSEWindow",&g_CLOSEValue,MaxValue,onChange_CLOSE);
	onChange_CLOSE(0,0);

	namedWindow("GRADIENTWindow",WINDOW_NORMAL);
	createTrackbar("GRADIENT","GRADIENTWindow",&g_GRADIENTValue,MaxValue,onChange_GRADIENT);
	onChange_GRADIENT(0,0);

	namedWindow("TOPHATWindow",WINDOW_NORMAL);
	createTrackbar("TOPHAT","TOPHATWindow",&g_TOPHATValue,MaxValue,onChange_TOPHAT);
	onChange_TOPHAT(0,0);

	namedWindow("BLACKHATWindow",WINDOW_NORMAL);
	createTrackbar("BLACKHAT","BLACKHATWindow",&g_BLACKHATValue,MaxValue,onChange_BLACKHAT);
	onChange_BLACKHAT(0,0);

	waitKey();
	return 0;
}

2.数码管

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.彩色图片

DILATE:各光点扩散
ERODE:各暗点扩散
OPEN:光点流失(open),更暗【消除细小物体,在纤细点处分离物体,平滑较大物体的边界】
CLOSE:光电保存(close),更亮【排除小型黑洞】
GRADIENT:Size()=1时得到线稿
TOPHAT:保留颜色,Size()=最大就是原图
BLACKHAT:不保留颜色,像是X光,Size()最大=X光图

猜你喜欢

转载自blog.csdn.net/sandalphon4869/article/details/94576278