Javascript图像处理—图像形态学(膨胀与腐蚀)

 更新时间:2013年01月04日 08:59:47   作者:  
上一篇文章,我们讲解了图像处理中的阈值函数,这一篇文章我们来做膨胀和腐蚀函数
前言

上一篇文章,我们讲解了图像处理中的阈值函数,这一篇文章我们来做膨胀和腐蚀函数。

膨胀与腐蚀

说概念可能很难解释,我们来看图,首先是原图:

Original image

膨胀以后会变成这样:

Dilation result - Theory example

腐蚀以后则会变成这样:

Erosion result - Theory example

看起来可能有些莫名其妙,明明是膨胀,为什么字反而变细了,而明明是腐蚀,为什么字反而变粗了。

实际上,所谓膨胀应该指

较亮色块膨胀。

而所谓腐蚀应该指

较亮色块腐蚀。

上面图里面,由于背景白色是较亮色块,所以膨胀时就把黑色较暗色块的字压扁了……相反腐蚀时,字就吸水膨胀了……

用数学公式表示就是

说白了就是在指定大小的内核里找最暗或者最亮的像素点,并用该点替换掉内核锚点上的像素。 

 

实现

首先我们来实现膨胀dilate函数。

复制代码 代码如下:

var dilate = function(__src, __size, __borderType, __dst){
__src || error(arguments.callee, IS_UNDEFINED_OR_NULL/* {line} */);
if(__src.type && __src.type == "CV_RGBA"){
var width = __src.col,
height = __src.row,
size = __size || 3,
dst = __dst || new Mat(height, width, CV_RGBA),
dstData = dst.data;

var start = size >> 1;
var withBorderMat = copyMakeBorder(__src, start, start, 0, 0, __borderType),
mData = withBorderMat.data,
mWidth = withBorderMat.col;

var newOffset, total, nowX, offsetY, offsetI, nowOffset, i, j;

if(size & 1 === 0){
error(arguments.callee, UNSPPORT_SIZE/* {line} */);
return __src;
}

for(i = height; i--;){
offsetI = i * width;
for(j = width; j--;){
newOffset = 0;
total = 0;
for(y = size; y--;){
offsetY = (y + i) * mWidth * 4;
for(x = size; x--;){
nowX = (x + j) * 4;
nowOffset = offsetY + nowX;
(mData[nowOffset] + mData[nowOffset + 1] + mData[nowOffset + 2] > total) && (total = mData[nowOffset] + mData[nowOffset + 1] + mData[nowOffset + 2]) && (newOffset = nowOffset);
}
}
dstData[(j + offsetI) * 4] = mData[newOffset];
dstData[(j + offsetI) * 4 + 1] = mData[newOffset + 1];
dstData[(j + offsetI) * 4 + 2] = mData[newOffset + 2];
dstData[(j + offsetI) * 4 + 3] = mData[newOffset + 3];
}
}

}else{
error(arguments.callee, UNSPPORT_DATA_TYPE/* {line} */);
}
return dst;
};

这行代码里面,我们先用RGB的数值和与上一个最大值total对比,然后如果新的值比较大,就把新的值赋给total,并把新的偏移量newOffset赋值当前偏移量nowOffset。

然后整个内核大小的面积循环完了就可以找到一个最大的total以及对应的偏移量newOffset。就可以赋值了:

dstData[(j + offsetI) * 4] = mData[newOffset];
dstData[(j + offsetI) * 4 + 1] = mData[newOffset + 1];
dstData[(j + offsetI) * 4 + 2] = mData[newOffset + 2];
dstData[(j + offsetI) * 4 + 3] = mData[newOffset + 3];

那么腐蚀erode函数则相反,找一个最小的值就行了。

复制代码 代码如下:

var erode = function(__src, __size, __borderType, __dst){
__src || error(arguments.callee, IS_UNDEFINED_OR_NULL/* {line} */);
if(__src.type && __src.type == "CV_RGBA"){
var width = __src.col,
height = __src.row,
size = __size || 3,
dst = __dst || new Mat(height, width, CV_RGBA),
dstData = dst.data;

var start = size >> 1;
var withBorderMat = copyMakeBorder(__src, start, start, 0, 0, __borderType),
mData = withBorderMat.data,
mWidth = withBorderMat.col;

var newOffset, total, nowX, offsetY, offsetI, nowOffset, i, j;

if(size & 1 === 0){
error(arguments.callee, UNSPPORT_SIZE/* {line} */);
return __src;
}

for(i = height; i--;){
offsetI = i * width;
for(j = width; j--;){
newOffset = 0;
total = 765;
for(y = size; y--;){
offsetY = (y + i) * mWidth * 4;
for(x = size; x--;){
nowX = (x + j) * 4;
nowOffset = offsetY + nowX;
(mData[nowOffset] + mData[nowOffset + 1] + mData[nowOffset + 2] < total) && (total = mData[nowOffset] + mData[nowOffset + 1] + mData[nowOffset + 2]) && (newOffset = nowOffset);
}
}
dstData[(j + offsetI) * 4] = mData[newOffset];
dstData[(j + offsetI) * 4 + 1] = mData[newOffset + 1];
dstData[(j + offsetI) * 4 + 2] = mData[newOffset + 2];
dstData[(j + offsetI) * 4 + 3] = mData[newOffset + 3];
}
}

}else{
error(arguments.callee, UNSPPORT_DATA_TYPE/* {line} */);
}
return dst;
};

效果

相关文章

  • javascript刷新父页面方法汇总详解

    javascript刷新父页面方法汇总详解

    这篇文章主要介绍了javascript刷新父页面方法汇总详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • layui自定义验证,用ajax查询后台是否有重复数据,form.verify的例子

    layui自定义验证,用ajax查询后台是否有重复数据,form.verify的例子

    今天小编就为大家分享一篇layui自定义验证,用ajax查询后台是否有重复数据,form.verify的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • JavaScript异步加载浅析

    JavaScript异步加载浅析

    这篇文章主要介绍了JavaScript异步加载浅析,本文讲解了脚本延迟执行、脚本的完全并行化、可编程的脚本加载等内容,需要的朋友可以参考下
    2014-12-12
  • js实现随机点名小功能

    js实现随机点名小功能

    这篇文章主要为大家详细介绍了js实现随机点名小功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • SharedWorker 多页面相互通信示例详解

    SharedWorker 多页面相互通信示例详解

    这篇文章主要为大家介绍了SharedWorker 多页面相互通信示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • Bootstrap响应式侧边栏改进版

    Bootstrap响应式侧边栏改进版

    这篇文章主要为大家详细介绍了Bootstrap响应式侧边栏改进版,结合导航条和下拉菜单进行改进,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • js对数字的格式化使用说明

    js对数字的格式化使用说明

    Javascript也提供了对数字进行格式化输出的支持,需要的朋友可以参考下。
    2011-01-01
  • canvas绘图不清晰的解决方案

    canvas绘图不清晰的解决方案

    本文主要介绍了canvas绘图不清晰的解决方案,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • 一文带你搞懂JavaScript中转义字符的使用

    一文带你搞懂JavaScript中转义字符的使用

    说起转义字符,大家最先想到的肯定是使用反斜杠,这也是我们最常见的,很多编程语言都支持。除了反斜杠以外,在前端开发中,还有其他几种转义字符,也是较常见的,本文将对这些做一个总结
    2023-02-02
  • JS基于面向对象实现的选项卡效果示例

    JS基于面向对象实现的选项卡效果示例

    这篇文章主要介绍了JS基于面向对象实现的选项卡效果,结合实例形式分析了javascript基于面向对象技术动态操作页面元素的流程与相关注意事项,需要的朋友可以参考下
    2016-12-12

最新评论