您的位置:首页 > 其它

图像处理算法系列 第六章 图像形态变化 膨胀 腐蚀 开运算 闭运算

2013-04-15 17:09 411 查看

前言

这几个词语显得十分专业了,我刚接触的时候完全也不太明白,这些算法的目的和意义,但是自己查阅了很多资料,又自己编写了一下代码,发现其实并不是那么难理解。

纸上得来终觉浅,绝知此事要躬行。闲话少说了

一 概念

1 腐蚀
腐蚀这个词大家应该不陌生了,以前化学里面经常会提到这个词,大家回忆一下,就能明白,物体(一般是金属)的表面被酸性物质侵蚀,导致失去光泽之类,或者体积缩小。因为不是专业的找化学用语,只是大概说明这个意思。
那么图像腐蚀呢?简单的将就是原图像经过一个参考矩阵的腐蚀之后,图像的周边变小的一种操作。那下图 来说吧


腐蚀之后


可以看出来字体明显纤细了很多。那么怎么实现呢?看着十分的奇特。

本文参考下面两篇文章。
/article/7052315.html
http://vipbase.net/ipbook/chap06.htm
嘿嘿,转载需要声明一下,尊重别人的劳动哈。

我自己理解了一下,腐蚀这个词确实很生动。 腐蚀的目标就是原图像, 腐蚀的酸性物质就是我们需要创建的矩阵。我们通过创建的矩阵将原图像进行了腐蚀。
本文只讲腐蚀矩阵是长方形的,其他形状的原理是类似的。上面的两个文章中都是对二值化之后进行操作,实际上可以扩展到所有图像。不一定要二值化。

以灰度图为例子吧,简单一点

灰度图的像素

3030405070
4050607020
3050802025
3344667799
4466889922
参考矩阵

111
111
111
也就是说 我们根据参考矩阵,然后找到灰度图中对应参考矩阵范围内,最小的那个值,将中间的值(标为红色)的变成最小值。

以下面蓝色区域为例子:

灰度图的像素

3030405070
4050607020
3050802025
3344667799
4466889922
可以看到蓝色区域内最小值是20,则将中间的60变成20.
结果如下:

灰度图的像素

3030405070
4050207020
3050802025
3344667799
4466889922
将上面的图片都经过刚才的操作,可以得到下面的结果

灰度图的像素

3030405070
4030302020
3030202025
3333202099
4466889922
可以看到中间的区域都发生了变化,之前我犯了个错误,以为每次腐蚀完之后,在目标图像上进一步腐蚀,那样整个图片颜色不都一样了么?其实腐蚀的操作源应该一直是原始图像。

2 膨胀
这个我就不细讲了,和腐蚀是逆运算,改两行代码就行了 直接上图了


膨胀


3 开运算
就是先膨胀, 再腐蚀



4 闭运算
先腐蚀, 在膨胀



效果图来自opencv。

三 代码

void ErosionImage(Mat src, Mat &dst, int size)
{
dst.create(src.size(),src.type());
uchar *p, *q;

int maskRows = 2*size + 1;
int maskCols = 2*size + 1;

int channels = src.channels();
int rows = src.rows;
int cols = src.cols;

for (int i = 0 ; i< rows - maskRows; i++)
{

p = src.ptr<uchar>(i);
for (int j = 0; j < cols - maskCols ;j++)
{
uchar minB = p[(j + maskCols /2)*channels ];
uchar minG = p[(j + maskCols /2)*channels + 1];
uchar minR = p[(j + maskCols /2)*channels + 2];

for (int k = 0; k <maskRows;k++)
{
p = src.ptr<uchar>(i+k);
for (int l = 0; l< maskCols;l++)
{
//if (p[(l+j) *channels] < minB  &&p[(l+j)*channels+1] < minG &&p[(l+j)*channels+2] < minR)写错了,之前的判断。
if (p[(l+j) *channels] + p[(l+j)*channels+1]+p[(l+j)*channels+2] < minB + minG +  minR )
{
minB = p[(l+j) *channels];
minG = p[(l+j) *channels+1];
minR = p[(l+j) *channels+2];
}
}
}

q = dst.ptr<uchar>(i + maskRows/2);
q[(j + maskCols /2)*channels ] = minB;
q[(j + maskCols /2)*channels +1] = minG;
q[(j + maskCols /2)*channels + 2] = minR;
}
}
}


将上面红色那行小于号改成大于号 就是膨胀算法

if if (p[(l+j) *channels] + p[(l+j)*channels+1]+p[(l+j)*channels+2] < minB + minG +  minR )


这里就不写了。

四效果

本来想放lena的图片,但是腐蚀之后效果太恐怖了,就拿这只鱼做实验吧,下面是原始图片。



半径为11原始方法半径为11本文方法


半径为11原始方法半径为11本文方法


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐