形态学图像处理一般应用于二进制图像。
核 :可以是任何形状和大小,拥有一个单独定义的参考点,称为锚点。多数情况下,核是一个小的,中间有参考点和实心正方形或者圆盘。
核的构造:
getStructuringElement();
第一个参数:表示内核的形状。MORPH_RECT矩形,MORPH_CROSS交叉形,MORPH_ELLIPESE椭圆形。
基本形态学操作
功能:
- 消除噪声。
- 分割出独立的图像元素,在图像中连接相邻的元素。
- 求出图像的梯度。
腐蚀
理解: 低暗部分的扩长。
核心思想: 求局部最小值。核覆盖区域内的像素最小值赋给锚点。
void erode(InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor=Point(-1, -1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue()
);
- 第一个参数:
- 第二个参数:
- 第三个参数:
- 第四个参数:
- 第五个参数:
- 第六个参数:
- 第七个参数:
膨胀
理解: 高亮部分的扩张
核心思想: 求局部最大值。核覆盖区域内的像素最大值赋给锚点。
void dilate(InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor = Point(-1, -1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue()
);
- 第一个参数:
- 第二个参数:
- 第三个参数:
- 第四个参数:
- 第五个参数:
- 第六个参数:
- 第七个参数:
高级形态学操作
开运算
先腐蚀后膨胀
消除小物体,
闭运算
通俗解释:先膨胀后腐蚀。
dst = clese(src,element) = erode(dilate(src, element))
功能:排除小型黑色区域。
形态学梯度
通俗解释:膨胀图和腐蚀图之差。
功能:使二值图像的边缘突出出来。保留物体的边缘轮廓。
顶帽
主要思想:原图像与开运算的结果图之差。
功能:突出比原图轮廓周围更亮的区域。
应用:
黑帽
闭运算的结果图和原图像之差。
功能:突出比原图像轮廓周围区域更暗的区域。
应用:得到完美的轮廓。
void morphologyEx(InputArray src,
OutputArray dst,
int op,
InputArray kernel,
Point anchor = Point(-1, -1),
int iterations = 1,
int borderTyper = BORDER_CONSTANT,
constScalar& borderValue = morphologyDefaultBorderValue()
);
- 第一个参数:
- 第二个参数:
- 第三个参数:形态学运算的类型。决定switch里的选择。
- 第四个参数:运算内核。
- 第五个参数:
- 第六个参数:迭代函数的次数,默认为1。
- 第七个参数:
- 第八个参数:
源码详解:
void morphologyEx(InputArray _src,
OutputArray _dst,
int op,
InputArray kernel,
Point anchor,
int iterations = 1,
int borderTyper,
constScalar& borderValue );
{
//复制Mat数据到临时变量
Mat src = _src.getMat();
Mat temp;
_dst.create(src.size(), src.type());
Mat dst = _dst.getMat();
// 一个大的switch,根据不同的标识符获取不同的操作
switch(op)
{
case MORPH_ERODE:
{
erode(src, dst, kernel, anchor, iterations, borderType, borderValue);
break;
}
case MORPH_DILATE:
{
dilate(src, dst, kernel, anchor, erations, borderType, borderValue);
break;
}
case MORPH_OPEN:
{
erode(src, dst, kernel, anchor, erations, borderType, borderValue);
break;
}
case CV_MOP_CLOSE:
{
dilate(src, dst, kernel, anchor, erations, borderType, borderValue);
erode(src, dst, kernel, anchor, erations, borderType, borderValue);
break;
}
case CV_MOP_GRADIENT:
{
erode(src, dst, kernel, anchor, erations, borderType, borderValue);
dilate(src, dst, kernel, anchor, erations, borderType, borderValue);
dst -= temp;
break;
}
case CV_MOP_TOPHAT:
{
if(src.data != dst.data)
{
temp = dst;
}
erode(src, dst, kernel, anchor, erations, borderType, borderValue);
dilate(src, dst, kernel, anchor, erations, borderType, borderValue);
dst = src - temp;
break;
}
case CV_MOP_BLACKHAT:
{
if(src.data != dst.data)
{
temp = dst;
}
dilate(src, dst, kernel, anchor, erations, borderType, borderValue);
erode(src, dst, kernel, anchor, erations, borderType, borderValue);
dst = temp - src;
break;
}
default:
CV_Error(CV_StsBadArg, "unknow morphological operation");
}
}