opencv笔记——膨胀与腐蚀

推荐博主点击这里

图像形态学即数学形态学(Mathematical morphology)是一门建立在格伦和拓扑学基础上的图像分析学科,是数学形态学图像处理的基本理论。

最基本的形态学操作是:膨胀(dilation)和腐蚀(erosion);

  • 参数详解:
    1.定义核(获取结构元素)——getStructuringElement()
    Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1))
    shape:模板形狀,有MORPH_RECT、MORPH_ELLIPSE、MORPH_CROSS三種可選。
    ksize:模板尺寸。
    2.膨胀——dilate()
    dilate(const Mat &src, Mat &dst, Mat kernel, Point anchor=Point(-1,-1), int iterations=1)
    src:输入图像
    dst:目标图像
    kernel:結構元素,如果kernel=Mat()則為預設的3×3矩形,越大膨脹效果越明顯。
    anchor:原點位置,預設為結構元素的中央。
    iterations:執行次數,預設為1次,執行越多次膨脹效果越明顯。
    3.腐蚀——erode()
    erode(const Mat &src, Mat &dst, Mat kernel, Point anchor=Point(-1,-1), int iterations=1)
    src:输入图像
    dst:输出图像
    kernel:結構元素,如果kernel=Mat()則為預設的3×3矩形,越大侵蝕效果越明顯。
    anchor:原點位置,預設為結構元素的中央。
    iterations:執行次數,預設為1次,執行越多次侵蝕效果越明顯。

膨胀和腐蚀的主要用途:
消除噪声;
分割出独立的图像元素,在图像中连接相邻的元素;
寻找图像中明显的极大值或极小值区;
求出图像的梯度;
【注】:
腐蚀和膨胀是对像素值大的部分而言的,即高亮白部分而不是黑色部分;膨胀是图像中的高亮部分进行膨胀,领域扩张,效果图拥有比原图更大的高亮区域;腐蚀是图像中的高亮部分被腐蚀掉,领域缩减,效果图拥有比原图更小的高亮区域;

  • 膨胀原理:
    膨胀:求局部最大值;①定义一个卷积核B,核可以是任何的形状和大小,且拥有一个单独定义出来的参考点-锚点(anchorpoint);通常和为带参考点的正方形或者圆盘,可将核称为模板或掩膜;②将核B与图像A进行卷积,计算核B覆盖区域的像素点最大值;③将这个最大值赋值给参考点指定的像素;因此,图像中的高亮区域逐渐增长。
  • 腐蚀原理:
    腐蚀:局部最小值(与膨胀相反);①定义一个卷积核B,核可以是任何的形状和大小,且拥有一个单独定义出来的参考点-锚点(anchorpoint);通常和为带参考点的正方形或者圆盘,可将核称为模板或掩膜;②将核B与图像A进行卷积,计算核B覆盖区域的像素点最小值;③将这个最小值赋值给参考点指定的像素;因此,图像中的高亮区域逐渐减小。

首先,定义核(获取结构元素)——getStructuringElement()

形态学其他操作,基于膨胀和腐蚀,利用morphologyEx()函数进行操作.

  • 开运算(参数为MORPH_OPEN)
  • 闭运算(参数为MORPH_CLOSE)
  • 顶帽(参数为MORPH_TOPHAT)
  • 黑帽(参数为MORPH_BLACKHAT)

膨胀就是对图像高亮部分进行“领域扩张”,效果图拥有比原图更大的高亮区域;腐蚀是原图中的高亮区域被蚕食,效果图拥有比原图更小的高亮区域。
膨胀
膨胀就是求局部最大值的操作,从图像直观看来,就是将图像光亮部分放大,黑暗部分缩小。
开运算:先腐蚀再膨胀,用来消除小物体
闭运算:先膨胀再腐蚀,用于排除小型黑洞
形态学梯度:就是膨胀图与俯视图之差,用于保留物体的边缘轮廓。
顶帽:原图像与开运算图之差,用于分离比邻近点亮一些的斑块。
黑帽:闭运算与原图像之差,用于分离比邻近点暗一些的斑块。
opencv里有一个很好的函数getStructuringElement,我们只要往这个函数传相应的处理参数,就可以进行相应的操作了,使用起来非常方便。

参考代码

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
//declaration of functions
bool mydilate();//dilate
bool myerode();//erode
bool mymorph_open();//MORPH_OPEN
bool mymorph_close();//MORPH_CLOSE
bool mymorph_gradient();//MORPH_GRADIENT
bool mymorph_tophat();//MORPH_TOPHAT
bool mymorph_blackhat();//MORPH_BLACKHAT
//bool mymorph_erode();//MORPH_ERODE
//bool mymorph_dilate();//MORPH_DILATE
Mat srcimage=imread("C:/Users/xihua/Pictures/Saved Pictures/2.jpg");
int main()
{
	if(!srcimage.data) {
		cout<<"No image!"<<endl; return -1;
	}
	namedWindow("srcimage");
	imshow("srcimage",srcimage);
	waitKey(0);
	//function call
	mydilate();//bool mymorph_dilate();//MORPH_DILATE
	myerode();//bool mymorph_erode();//MORPH_ERODE
	mymorph_open();
	mymorph_close();
	mymorph_gradient();
	mymorph_tophat();
	mymorph_blackhat();
	return 0;
}

bool mydilate() {
	Mat dilateimage;
	Mat element=getStructuringElement(MORPH_RECT,Size(5,5),Point(-1,-1));//Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1))
	dilate(srcimage,dilateimage,element,Point(-1,-1),1);//dilate(const Mat &src, Mat &dst, Mat kernel, Point anchor=Point(-1,-1), int iterations=1)
	if(!dilateimage.data) {
		cout<<"No image!"<<endl; return false;
	}
	namedWindow("dilate");
	imshow("dilate",dilateimage);
	waitKey(0);
	return true;
}
bool myerode() {
	Mat erodeimage;
	Mat element=getStructuringElement(MORPH_RECT,Size(5,5),Point(-1,-1));
	erode(srcimage,erodeimage,element,Point(-1,-1),1);//erode(const Mat &src, Mat &dst, Mat kernel, Point anchor=Point(-1,-1), int iterations=1)
	if(!erodeimage.data) {
		cout<<"No image!"<<endl; return false;
	}
	namedWindow("erode");
	imshow("erode",erodeimage);
	waitKey(0);
	return true;
}
bool mymorph_open() {
	Mat openimage;
	Mat element=getStructuringElement(MORPH_RECT,Size(5,5),Point(-1,-1));
	morphologyEx(srcimage,openimage,MORPH_OPEN,element);
	if(!openimage.data) {
		cout<<"No image!"<<endl; return false;
	}
	namedWindow("MORPH_OPEN");
	imshow("MORPH_OPEN",openimage);
	waitKey(0);
	return true;
}
bool mymorph_close() {
	Mat closeimage;
	Mat element=getStructuringElement(MORPH_RECT,Size(5,5),Point(-1,-1));
	morphologyEx(srcimage,closeimage,MORPH_CLOSE,element);
	if(!closeimage.data) {
		cout<<"No image!"<<endl; return false;
	}
	namedWindow("MORPH_CLOSE");
	imshow("MORPH_CLOSE",closeimage);
	waitKey(0);
	return true;
}
bool mymorph_gradient() {
	Mat gradientimage;
	Mat element=getStructuringElement(MORPH_RECT,Size(5,5),Point(-1,-1));
	morphologyEx(srcimage,gradientimage,MORPH_GRADIENT,element);
	if (!gradientimage.data) {
		cout<<"No image!"<<endl; return false;
	}
	namedWindow("MORPH_GRADIENT");
	imshow("MORPH_GRADIENT",gradientimage);
	waitKey(0);
	return true;
}
bool mymorph_tophat() {
	Mat tophatimage;
	Mat element=getStructuringElement(MORPH_RECT,Size(5,5),Point(-1,-1));
	morphologyEx(srcimage,tophatimage,MORPH_TOPHAT,element);
	if (!tophatimage.data) {
		cout<<"No image!"<<endl; return false;
	}
	namedWindow("MORPH_TOPHAT");
	imshow("MORPH_TOPHAT",tophatimage);
	waitKey(0);
	return true;
}
bool mymorph_blackhat() {
	Mat blackhatimage;
	Mat element=getStructuringElement(MORPH_RECT,Size(5,5),Point(-1,-1));
	morphologyEx(srcimage,blackhatimage,MORPH_BLACKHAT,element);
	if(!blackhatimage.data) {
		cout<<"No image!"<<endl; return false;
	}
	namedWindow("MORPH_BLACKHAT");
	imshow("MORPH_BLACKHAT",blackhatimage);
	waitKey(0);
	return true;
}

猜你喜欢

转载自blog.csdn.net/pipihan21/article/details/105307827
今日推荐