形态学操作
形态学(形态学)常应用在生物学中,研究动植物的形态和结构;
图像形态学即数学形态学(Mathematical morphology)是一门建立在格伦和拓扑学基础上的图像分析学科,是数学形态学图像处理的基本理论;
常见图像形态***算:腐蚀,膨胀,开运算,闭运算,骨架抽取,极线腐蚀,击中击不中变换,顶帽变换,颗粒分析,流域变换,形态学梯度等;
最基本的形态学操作是:膨胀(扩张)和腐蚀(侵蚀);
膨胀和腐蚀的主要用途:
消除噪声;
分割出独立的图像元素,在图像中连接相邻的元素;
寻找图像中明显的极大值或极小值区;
求出图像的梯度;
【注】:
腐蚀和膨胀是对像素值大的部分而言的,即高亮白部分而不是黑色部分;
膨胀是图像中的高亮部分进行膨胀,领域扩张,效果图拥有比原图更大的高亮区域;
腐蚀是图像中的高亮部分被腐蚀掉,领域缩减,效果图拥有比原图更小的高亮区域;
-
膨胀
原理:求局部最大值;
实现方法:
①定义一个卷积核B,核可以是任何的形状和大小,且拥有一个单独定义出来的参考点 - 锚点(anchorpoint);
通常和为带参考点的正方形或者圆盘,可将核称为模板或掩膜;
②将核乙与图像甲进行卷积,计算核乙覆盖区域的像素点最大值;
③将这个最大值赋值给参考点指定的像素;
因此,图像中的高亮区域逐渐增长。
-
腐蚀
腐蚀原理:
腐蚀:局部最小值(与膨胀相反);
①定义一个卷积核B,核可以是任何的形状和大小,且拥有一个单独定义出来的参考点 - 锚点(anchorpoint);
通常和为带参考点的正方形或者圆盘,可将核称为模板或掩膜;
②将核乙与图像甲进行卷积,计算核乙覆盖区域的像素点最小值;
③将这个最小值赋值给参考点指定的像素;
因此,图像中的高亮区域逐渐减小。
OpenCV的中膨胀函数-dilate()
格式:
空隙扩张(
InputArray src,//输入
OutputArray dst,//输出
InputArray kernel,//核大小
点锚点=点(-1,-1),//锚位置,( - 1,-1)为中心
int iterations = 1,//迭代次数
int borderType = BORDER_CONSTANT,//图像边界像素模式
const Scalar&borderValue = morphologyDefaultBorderValue()//边界值
)
【注】:
关于核,一般配合getStructuringElement()使用;
getStructuringElement():返回指定形状和尺寸的结构元素;
格式:
getStructuringElement(int shape,Size ksize,Point anchor = Point(-1,-1));
参数:
形状:表核的形状,矩形MORPH_RECT;交叉形MORPH_CROSS;椭圆形MORPH_ELLIPSE;
ksize:核尺寸大小;
锚:锚点的位置,锚点只影响形态***算结果的偏移;
OpenCV的中腐蚀函数-erode()
格式:
无效(
InputArray src,//输入
OutputArray dst,//输出
InputArray kernel,//核大小
点锚点=点(-1,-1),//锚位置,( - 1,-1)为中心
int iterations = 1,//迭代次数
int borderType = BORDER_CONSTANT,//图像边界像素模式
const Scalar&borderValue = morphologyDefaultBorderValue()//边界值
)
开闭操作的目的:
开操作可以平滑物体轮廓,断开狭窄的间断和消除细小的突出物。它具有消除细小物体,在纤细处分离物体和平滑较大物体边界的作用。采用上图的结构B对原件进行开操作,
闭操作可以消弭狭窄的间断,消除小的孔洞。先膨胀后腐蚀的操作称之为闭操作。它具有填充物体内细小空洞,连接邻近物体和平滑边界的作用。采用上图的结构对原件进行闭操作,
-
形态学开运算:
- 开运算(Open Operation):先腐蚀后膨胀的过程;
功能:
消除小物体;
在纤细处分离物体;
平滑较大的边界并不明显改变其面积;
-
形态学闭运算:
- 闭运算(Closing Openration),先膨胀后腐蚀;
功能:
排除小型黑洞(黑斑);
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
Mat src1, src2;
int ment_size=10;
void demo(int,void*);
int main()
{
src1 = imread("C:\\Users\\马迎伟\\Desktop\\douyin.jpg");
if (src1.empty())
{
cout << "could not find src1" << endl;
return -1;
}
namedWindow("output",CV_WINDOW_AUTOSIZE);
createTrackbar("elementsize", "output", &ment_size, 21, demo);
demo(0,0);
imshow("output",src2);
waitKey(0);
return 0;
}
void demo(int ,void*)
{
int size = 2*ment_size+1;
//获取 kernel的形状
Mat ds = getStructuringElement(MORPH_RECT, Size(size, size),Point(-1,-1));
//dilate(src1, src2, ds); //膨胀
erode(src1,src2,ds,Point(-1,-1)); //腐蚀
}
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
Mat src1, src2;
int main()
{
src1 = imread("C:\\Users\\马迎伟\\Desktop\\douyin.jpg");
if (src1.empty())
{
cout << "could not find src1" << endl;
return -1;
}
namedWindow("output", CV_WINDOW_AUTOSIZE);
//开 操作,先腐蚀后膨胀; (深色背景中去 浅色)
//闭 操作,先膨胀后腐蚀; (浅色背景中去 深色)
Mat kernel = getStructuringElement(MORPH_RECT,Size(40,40),Point(-1,-1));
//cout << kernel << endl;
//morphologyEx(src1,src2,CV_MOP_OPEN,kernel);
morphologyEx(src1, src2, CV_MOP_TOPHAT, kernel);
//imshow("output", src2);
//形态学梯度,又称为基本梯度,(膨胀减去腐蚀)CV_MOP_GRADIENT
//黑帽 (闭操作与原图像的差值) CV_MOP_BLACKHAT
//顶帽 (原图像与开操作的差值) CV_MOP_TOPHAT
imshow("output",src2);
waitKey(0);
return 0;
}