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

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

一:基本原理

膨胀与腐蚀是图像形态学两个基本操作之一,传统的代码实现都是基于二维窗口卷积模式,对于正常的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位):
这里写图片描述
无论是卷积还是高斯模糊,还是形态学操作,理论上都是卷积计算,但是在实际编码过程中基于对计算耗时考虑都是进行了各种有效变换从而提高计算速度与减少执行时间,所以对于任何看似简单的图像操作,所以理论一定要联系实践!不然长期如此的结果就是眼高手低! 愿与各位共勉!祝各位五一劳动节快乐!

请继续关注本博客与本人微信公众号!
专注图像处理与OpenCV学习!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值