推荐博主点击这里
图像形态学即数学形态学(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;
}