洪水填充算法_图像处理之泛洪填充算法(Flood Fill Algorithm)

本文详细介绍了洪水填充算法在图像处理中的应用,包括4连接、8连接以及扫描线方法实现。此外,还讨论了算法的性能问题及优化策略,如使用堆栈数据结构来避免栈溢出。
摘要由CSDN通过智能技术生成

packagecom.gloomyfish.paint.fill;importjava.awt.image.BufferedImage;importcom.gloomyfish.filter.study.AbstractBufferedImageOp;public class FloodFillAlgorithm extendsAbstractBufferedImageOp {privateBufferedImage inputImage;private int[] inPixels;private intwidth;private intheight;//stack data structure

private int maxStackSize = 500; //will be increased as needed

private int[] xstack = new int[maxStackSize];private int[] ystack = new int[maxStackSize];private intstackSize;publicFloodFillAlgorithm(BufferedImage rawImage) {this.inputImage =rawImage;

width=rawImage.getWidth();

height=rawImage.getHeight();

inPixels= new int[width*height];

getRGB(rawImage,0, 0, width, height, inPixels );

}publicBufferedImage getInputImage() {returninputImage;

}public voidsetInputImage(BufferedImage inputImage) {this.inputImage =inputImage;

}public int getColor(int x, inty)

{int index = y * width +x;returninPixels[index];

}public void setColor(int x, int y, intnewColor)

{int index = y * width +x;

inPixels[index]=newColor;

}public voidupdateResult()

{

setRGB( inputImage,0, 0, width, height, inPixels );

}/*** it is very low calculation speed and cause the stack overflow issue when fill

* some big area and irregular shape. performance is very bad.

*

*@paramx

*@paramy

*@paramnewColor

*@paramoldColor*/

public void floodFill4(int x, int y, int newColor, intoldColor)

{if(x >= 0 && x < width && y >= 0 && y

{

setColor(x, y, newColor);//set color before starting recursion

floodFill4(x + 1, y, newColor, oldColor);

floodFill4(x- 1, y, newColor, oldColor);

floodFill4(x, y+ 1, newColor, oldColor);

floodFill4(x, y- 1, newColor, oldColor);

}

}/***

*@paramx

*@paramy

*@paramnewColor

*@paramoldColor*/

public void floodFill8(int x, int y, int newColor, intoldColor)

{if(x >= 0 && x < width && y >= 0 && y < height &&getColor(x, y)== oldColor && getColor(x, y) !=newColor)

{

setColor(x, y, newColor);//set color before starting recursion

floodFill8(x + 1, y, newColor, oldColor);

floodFill8(x- 1, y, newColor, oldColor);

floodFill8(x, y+ 1, newColor, oldColor);

floodFill8(x, y- 1, newColor, oldColor);

floodFill8(x+ 1, y + 1, newColor, oldColor);

floodFill8(x- 1, y - 1, newColor, oldColor);

floodFill8(x- 1, y + 1, newColor, oldColor);

floodFill8(x+ 1, y - 1, newColor, oldColor);

}

}/***

*@paramx

*@paramy

*@paramnewColor

*@paramoldColor*/

public void floodFillScanLine(int x, int y, int newColor, intoldColor)

{if(oldColor == newColor) return;if(getColor(x, y) != oldColor) return;inty1;//draw current scanline from start position to the top

y1 =y;while(y1 < height && getColor(x, y1) ==oldColor)

{

setColor(x, y1, newColor);

y1++;

}//draw current scanline from start position to the bottom

y1 = y - 1;while(y1 >= 0 && getColor(x, y1) ==oldColor)

{

setColor(x, y1, newColor);

y1--;

}//test for new scanlines to the left

y1 =y;while(y1 < height && getColor(x, y1) ==newColor)

{if(x > 0 && getColor(x - 1, y1) ==oldColor)

{

floodFillScanLine(x- 1, y1, newColor, oldColor);

}

y1++;

}

y1= y - 1;while(y1 >= 0 && getColor(x, y1) ==newColor)

{if(x > 0 && getColor(x - 1, y1) ==oldColor)

{

floodFillScanLine(x- 1, y1, newColor, oldColor);

}

y1--;

}//test for new scanlines to the right

y1 =y;while(y1 < height && getColor(x, y1) ==newColor)

{if(x < width - 1 && getColor(x + 1, y1) ==oldColor)

{

floodFillScanLine(x+ 1, y1, newColor, oldColor);

}

y1++;

}

y1= y - 1;while(y1 >= 0 && getColor(x, y1) ==newColor)

{if(x < width - 1 && getColor(x + 1, y1) ==oldColor)

{

floodFillScanLine(x+ 1, y1, newColor, oldColor);

}

y1--;

}

}public void floodFillScanLineWithStack(int x, int y, int newColor, intoldColor)

{if(oldColor ==newColor) {

System.out.println("do nothing !!!, filled area!!");return;

}

emptyStack();inty1;booleanspanLeft, spanRight;

push(x, y);while(true)

{

x=popx();if(x == -1) return;

y=popy();

y1=y;while(y1 >= 0 && getColor(x, y1) == oldColor) y1--; //go to line top/bottom

y1++; //start from line starting point pixel

spanLeft = spanRight = false;while(y1 < height && getColor(x, y1) ==oldColor)

{

setColor(x, y1, newColor);if(!spanLeft && x > 0 && getColor(x - 1, y1) == oldColor)//just keep left line once in the stack

{

push(x- 1, y1);

spanLeft= true;

}else if(spanLeft && x > 0 && getColor(x - 1, y1) !=oldColor)

{

spanLeft= false;

}if(!spanRight && x < width - 1 && getColor(x + 1, y1) == oldColor) //just keep right line once in the stack

{

push(x+ 1, y1);

spanRight= true;

}else if(spanRight && x < width - 1 && getColor(x + 1, y1) !=oldColor)

{

spanRight= false;

}

y1++;

}

}

}private voidemptyStack() {while(popx() != - 1) {

popy();

}

stackSize= 0;

}final void push(int x, inty) {

stackSize++;if (stackSize==maxStackSize) {int[] newXStack = new int[maxStackSize*2];int[] newYStack = new int[maxStackSize*2];

System.arraycopy(xstack,0, newXStack, 0, maxStackSize);

System.arraycopy(ystack,0, newYStack, 0, maxStackSize);

xstack=newXStack;

ystack=newYStack;

maxStackSize*= 2;

}

xstack[stackSize-1] =x;

ystack[stackSize-1] =y;

}final intpopx() {if (stackSize==0)return -1;else

return xstack[stackSize-1];

}final intpopy() {int value = ystack[stackSize-1];

stackSize--;returnvalue;

}

@OverridepublicBufferedImage filter(BufferedImage src, BufferedImage dest) {//TODO Auto-generated method stub

return null;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值