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

时间:2022-05-07
本文章向大家介绍基于一维级联快速膨胀与腐蚀算法,主要内容包括一:基本原理、二:代码实现(Java语言实现)、三:耗时比较、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

一:基本原理

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

二:代码实现(Java语言实现)

基于一维级联快速腐蚀算法代码实现:

@Overridepublic 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);}

基于传统卷积腐蚀算法代码实现:

@Overridepublic 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位):

原图与对应不同结构元素大小腐蚀结果如下:

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