基于一维级联快速腐蚀与膨胀算法

简介: 基于一维级联快速腐蚀与膨胀算法

基于一维级联快速膨胀与腐蚀算法

一:基本原理

膨胀与腐蚀是图像形态学两个基本操作之一,传统的代码实现都是基于二维窗口卷积模式,对于正常的3x3窗口要八次与运算,而基于一维级联方式先X方向后Y方向只需要4次与运算即可。对于结构元素比较大的矩形来说,我们还可以通过连续的3x3的级联腐蚀或者膨胀来替代,假设对于11x11窗口大小腐蚀来说,正常的计算需要120次的与操作,而通过一维级联腐蚀只需要在X方向10次与操作,Y方向10次与操作,总计2x10=20次与操作即可实现。这样就极大的提高了二值图像腐蚀与膨胀的计算效率。图示如下:

二:代码实现

快速版本

package com.gloomyfish.ii.demo;

public class FastErode extends AbstractByteProcessor {
    private byte[] data;
    private int radius; // must be odd

    public FastErode() {
        this.radius = 25;
    }

    public void setRadius(int radius) {
        this.radius = radius;
        if(radius % 2 == 0) {
            throw new RuntimeException("invalid parameters");
        }
    }

    public void setData(byte[] data) {
        this.data = data;
    }

    @Override
    public void process(int width, int height) {
        int size = width*height;
        byte[] output = new byte[size];
        System.arraycopy(data, 0, output, 0, size);

        // X Direction
        int xr = radius/2;
        byte c = (byte)0;
        int offset = 0;
        for(int row=0; row<height; row++) {
            for(int col=0; col<width; col++) {
                c = data[row*width+col];
                if((c&0xff) == 0)continue;
                for(int x=-xr; x<=xr; x++) {
                    if(x==0)continue;
                    offset = x + col;
                    if(offset < 0) {
                        offset = 0;
                    }
                    if(offset >= width) {
                        offset = width - 1;
                    }
                    c &=data[row*width+offset];
                }
                if(c == 0){
                    output[row*width+col] = (byte)0;
                }
            }
        }
        System.arraycopy(output, 0, data, 0, size);

        // Y Direction
        int yr = radius/2;
        c = 0;
        offset = 0;
        for(int col=0; col<width; col++) {
            for(int row=0; row<height; row++) {
                c = data[row*width+col];
                if((c&0xff) == 0)continue;
                for(int y=-yr; y<=yr; y++) {
                    if(y == 0)continue;
                    offset = y + row;
                    if(offset < 0) {
                        offset = 0;
                    }
                    if(offset >= height) {
                        offset = height - 1;
                    }
                    c &=data[offset*width+col];
                }
                if(c == 0){
                    output[row*width+col] = (byte)0;
                }
            }
        }
        System.arraycopy(output, 0, data, 0, size);
    }
}

传统版本

@Override
public void process(int width, int height) {
    int size = width*height;
    byte[] output = new byte[size];
    IntIntegralImage grayii = new IntIntegralImage();
    grayii.setImage(data);
    grayii.process(width, height);
    int yr = radius/2;
    int xr = radius/2;
    System.arraycopy(data, 0, output, 0, size);
    byte c = 0;
    int nx=0, ny=0;

    for(int row=0; row<height; row++) {
        for(int col=0; col<width; col++) {
            c = data[row*width+col];
            if(c == 0)continue;
            for(int y=-yr; y<=yr; y++) {
                ny = y + row;
                if(ny < 0 || ny >= height){
                    ny = 0;
                }
                for(int x=-xr; x<=xr; x++) {
                    nx = x+col;
                    if(nx < 0 || nx >= width) {
                        nx = 0;
                    }
                    c &= data[ny*width+nx]&0xff;
                }
            }
            if(c == 0) {
                output[row*width+col] = (byte)0;
            }
        }
    }
    System.arraycopy(output, 0, data, 0, size);

}

三:耗时比较

对一张大小为381x244大小二值图像一维快速与传统腐蚀操作耗时比较结果如下(Win64,CPU i5, JDK8 64位):

无论是卷积还是高斯模糊,还是形态学操作,理论上都是卷积计算,但是在实际编码过程中基于对计算耗时考虑都是进行了各种有效变换从而提高计算速度与减少执行时间,所以对于任何看似简单的图像操作,所以理论一定要联系实践!不然长期如此的结果就是眼高手低! 愿与各位共勉!祝各位五一劳动节快乐!

相关文章
|
7月前
|
算法 计算机视觉 异构计算
基于FPGA的图像形态学腐蚀算法实现,包括tb测试文件和MATLAB辅助验证
基于FPGA的图像形态学腐蚀算法实现,包括tb测试文件和MATLAB辅助验证
|
7月前
|
算法
【MATLAB】语音信号识别与处理:一维信号NLM非局部均值滤波算法去噪及谱相减算法呈现频谱
【MATLAB】语音信号识别与处理:一维信号NLM非局部均值滤波算法去噪及谱相减算法呈现频谱
157 1
|
5月前
|
机器学习/深度学习 数据采集 算法
Python实现DBSCAN膨胀聚类模型(DBSCAN算法)项目实战
Python实现DBSCAN膨胀聚类模型(DBSCAN算法)项目实战
|
7月前
|
算法
MATLAB | 插值算法 | 一维interpl插值法 | 附数据和出图代码 | 直接上手
MATLAB | 插值算法 | 一维interpl插值法 | 附数据和出图代码 | 直接上手
331 0
|
7月前
|
算法
MATLAB | 插值算法 | 一维Lagrange插值法 | 附数据和出图代码 | 直接上手
MATLAB | 插值算法 | 一维Lagrange插值法 | 附数据和出图代码 | 直接上手
267 0
|
7月前
|
算法 计算机视觉 异构计算
基于FPGA的图像形态学膨胀算法实现,包括tb测试文件和MATLAB辅助验证
基于FPGA的图像形态学膨胀算法实现,包括tb测试文件和MATLAB辅助验证
|
算法 数据库
KNN算法的简单应用将一维数据集分类——打开就可以跑
KNN算法的简单应用将一维数据集分类——打开就可以跑
|
存储 人工智能 移动开发
【C++算法图解专栏】一篇文章带你掌握前缀和算法(一维+二维)
【C++算法图解专栏】一篇文章带你掌握前缀和算法(一维+二维)
212 0
【C++算法图解专栏】一篇文章带你掌握前缀和算法(一维+二维)
|
算法 数据可视化 数据挖掘
基于GMM的一维时序数据平滑算法
本文将介绍我们使用高斯混合模型(GMM)算法作为一维数据的平滑和去噪算法。
214 0
|
算法
连续向量最大和(一维模式识别)算法的分析与优化
输入:n个互相没有关联的数字(正负随机) 输出:该数组中连续数字的最大和     如在数组3 -4 5 2 -5 5 9 -9 -2 8中,连续数字最大和为5 2 -5 5 9这个数字序列的和,最大和为16 一、简单迭代算法     遇到这种问题,头脑中冒出的最直接最简单的就是这种算法。
856 0
下一篇
DataWorks