图像算法:图像形态学运算-膨胀、腐蚀、开闭
1、膨胀和腐蚀的主要用途:
消除噪声;
分割出独立的图像元素,在图像中连接相邻的元素;
寻找图像中明显的极大值或极小值区;
求出图像的梯度;
【注】:
腐蚀和膨胀是对像素值大的部分而言的,即高亮白部分而不是黑色部分;
膨胀是图像中的高亮部分进行膨胀,领域扩张,效果图拥有比原图更大的高亮区域;
腐蚀是图像中的高亮部分被腐蚀掉,领域缩减,效果图拥有比原图更小的高亮区域;
2、膨胀原理:
膨胀:求局部最大值;
①定义一个卷积核B,
核可以是任何的形状和大小,且拥有一个单独定义出来的参考点-锚点(anchorpoint);
通常和为带参考点的正方形或者圆盘,可将核称为模板或掩膜;
②将核B与图像A进行卷积,计算核B覆盖区域的像素点最大值;
③将这个最大值赋值给参考点指定的像素;
因此,图像中的高亮区域逐渐增长。

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

4、OpenCV中膨胀函数-dilate()
格式:
void dilate(
InputArray src,//输入
OutputArray dst, //输出
InputArray kernel, //核大小
Point anchor=Point(-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));
参数:
shape:表核的形状,矩形MORPH_RECT;交叉形MORPH_CROSS;椭圆形MORPH_ELLIPSE;
ksize:核尺寸大小;
anchor:锚点的位置,锚点只影响形态学运算结果的偏移;

5、OpenCV中腐蚀函数-erode()
格式:
void erode(
InputArray src,//输入
OutputArray dst, //输出
InputArray kernel, //核大小
Point anchor=Point(-1,-1),// 锚位置,(-1,-1)为中心
int iterations=1, //迭代次数
int borderType=BORDER_CONSTANT,//图像边界像素模式
const Scalar& borderValue=morphologyDefaultBorderValue()//边界值
)

6、形态学开运算:
开运算(Open Operation):先腐蚀后膨胀的过程;
功能:
消除小物体;
在纤细处分离物体;
平滑较大的边界并不明显改变其面积;

7、形态学闭运算:
闭运算(Closing Openration),先膨胀后腐蚀;
功能:
排除小型黑洞(黑斑);

8、OpenCV:morphologyEx()
功能:morphologyEx函数利用基本的膨胀和腐蚀技术,来执行更加高级形态学变换,
如开闭运算,形态学梯度,“顶帽”、“黑帽”等等。
void morphologyEx(
InputArray src, //
OutputArray dst,//
int op,//形态学运算的类型
InputArraykernel,
Pointanchor=Point(-1,-1),
intiterations=1,
intborderType=BORDER_CONSTANT,
constScalar& borderValue=morphologyDefaultBorderValue() );
【注】:
int op:表示形态学运算的类型,
MORPH_OPEN – 开运算(Opening operation)
MORPH_CLOSE – 闭运算(Closing operation)
MORPH_GRADIENT -形态学梯度(Morphological gradient)
MORPH_TOPHAT - “顶帽”(“Top hat”)
MORPH_BLACKHAT - “黑帽”(“Black hat“)
9、示例程序:
#include "cv.h"
#include "highgui.h"
using namespace cv;
int main(int argc, char* argv[])
{
Mat src = imread("misaka.jpg");
Mat dst;
//输入图像
//输出图像
//单元大小,这里是5*5的8位单元
//腐蚀位置,为负值取核中心
//腐蚀次数两次
erode(src,dst,Mat(5,5,CV_8U),Point(-1,-1),2);
imwrite("erode.jpg",dst);
//输入图像
//输出图像
//单元大小,这里是5*5的8位单元
//膨胀位置,为负值取核中心
//膨胀次数两次
dilate(src,dst,Mat(5,5,CV_8U),Point(-1,-1),2);
imwrite("dilate.jpg",dst);
//输入图像
//输出图像
//定义操作:MORPH_OPEN为开操作,MORPH_CLOSE为闭操作
//单元大小,这里是3*3的8位单元
//开闭操作位置
//开闭操作次数
morphologyEx(src,dst,MORPH_OPEN,Mat(3,3,CV_8U),Point(-1,-1),1);
imwrite("open.jpg",dst);
morphologyEx(src,dst,MORPH_CLOSE,Mat(3,3,CV_8U),Point(-1,-1),1);
imwrite("close.jpg",dst);
//定义核
//Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
//进行形态学操作
//morphologyEx(image,image, MORPH_CLOSE, element);
imshow("dst",dst);
waitKey();
return 0;
}