Image 泛洪填充算法-省去边缘

Image 泛洪填充算法-省去边缘,image,algorithm,image-processing,Image,Algorithm,Image Processing,到目前为止,我已经实现了一个泛洪填充算法。我想调整它,这样它就可以省去边缘了。为了证明这一点,我上传了一张图片: 图像1是我要修改的图像。图3是我的算法应该做的图像2是我当前的结果。 因此,在这种情况下,targetColor为白色,replacementColor为绿色 以下是我迄今为止所做工作的伪代码 doFloodFill(x,y,targetColor,replacementcolor){ if(x和y不在图像边界内){ 返回 } 如果(颜色(x,y)不是targetColor){ 返

到目前为止,我已经实现了一个泛洪填充算法。我想调整它,这样它就可以省去边缘了。为了证明这一点,我上传了一张图片:

图像1是我要修改的图像。图3是我的算法应该做的图像2是我当前的结果。

因此,在这种情况下,targetColor为白色,replacementColor为绿色

以下是我迄今为止所做工作的伪代码

doFloodFill(x,y,targetColor,replacementcolor){
if(x和y不在图像边界内){
返回
}
如果(颜色(x,y)不是targetColor){
返回
}
如果(颜色(x+1,y)不是FloodFill的目标颜色,并且颜色(x+1,y)不是replacementColor或
颜色(x-1,y)不是FloodFill的目标颜色,颜色(x-1,y)不是replacementColor或
颜色(x,y+1)不是FloodFill的目标颜色,颜色(x,y+1)不是replacementColor或
颜色(y,y-1)不是FloodFill的目标颜色,颜色(x,y-1)不是replacementColor){
返回;
}
image.setColor(x,y,replacementColor)
doFloodFill(x+3,y,targetcolor,replacementcolor)
doFloodFill(x-3、y、targetcolor、replacementcolor)
doFloodFill(x,y+3,targetcolor,replacementcolor)
doFloodFill(x、y-3、targetcolor、replacementcolor)
}
这个调整被应用到我的洪水填充中。不考虑它会导致一个正常工作的泛洪填充算法,没有任何问题。实际问题是:如何区分边缘像素和区域内具有不同颜色的像素


附言:我们可以假设x,y从区域内开始

首先以图像左上角的像素开始填充图像1中的黑色外部区域。使用尚未使用的颜色(例如紫色)或在归档过程中构建遮罩

然后像您那样在中心对象中填充白色区域绿色,但不调整算法。只是普通的洪水填充

最后,检查第二次填充中的所有像素,并将第一次填充边界的像素再次变为白色

你已经实现了你的目标。如果未使用遮罩,请确保再次填充第一次填充黑色产生的区域


无需调整洪水填充算法。

我也会选择洪水填充补充

不过,还有一个想法:

  • 像往常一样填海
  • 跟踪边框的一个像素:例如,最顶端的像素
  • 然后像老鼠一样沿着边界逃跑,让它再次变白
const canvas=document.querySelector('canvas');
常数M=`
00000000000000000000
00000110011111110000
00001111111110000000
00011111111111100000
00111111111101110010
01111111101111110010
01111111111111110110
01111111111111111110
01111111111111111100
01111111111111111100
01111111111111111100
01111111111111111000
00111111111111111000
00111111111111110000
00011111111111100000
00000000000000000000
`.trim().split('\n').map(x=>x.trim().split('').map(x=>parseInt(x)))
常数mat=({x,y},v)=>{
如果(v){
M[y][x]=v
}
返回M[y][x]
}
常量左=({x,y})=>({x:y,y:-x})
常数右=({x,y})=>({x:-y,y:x})
常量back=({x,y})=>({x:-x,y:-y})
const front=(pos,{x,y})=>({x:pos.x+x,y:pos.y+y})
常量碎片={
pos:{
x:5,
y:1
},
原文:{
x:5,
y:1
},
目录:{x:1,y:0},
atStart(){
返回this.pos.x===this.orig.x&&this.pos.y===this.orig.y
},
移动(){
if(this.atStart()&&mat(this.pos)==2){return false}
//左边的墙
if(mat(前(this.pos,左(this.dir))==0){
//前面的墙
if(mat(front(this.pos,this.dir))==0){
//右边的墙
if(mat(前面(this.pos,右边(this.dir)))==0{
this.dir=back(this.dir)
}否则{
this.dir=right(this.dir)
}
}
这个
}否则{
this.dir=左(this.dir)
}
这个。向前移动()
返回真值
},
向前移动(){
this.pos.x+=this.dir.x
this.pos.y+=this.dir.y
},
大便(){
mat({x:this.pos.x,y:this.pos.y},2)
},
雪碧(){
if(this.atStart()){return'X'}
如果(this.dir.x===-1&&this.dir.y===0){return'←' }
如果(this.dir.x==1&&this.dir.y==0){return'→'}
如果(this.dir.x==0&&this.dir.y==1){return'↓' }
如果(this.dir.x==0&&this.dir.y===1){return'↑' }
}
}
函数重画(){
const ctx=canvas.getContext('2d')
const dw=canvas.width/M[0]。长度
常数dh=画布高度/米长度
常量填充=({x,y},颜色)=>{
ctx.fillStyle=颜色
ctx.fillRect(x*dw,y*dh,dw,dh)
}
常量颜色={
1:‘绿色’,
0:'黑色',
2:‘白色’
}
M.forEach((世界其他地区,i)=>{
行forEach((el,j)=>{
填充({x:j,y:i},颜色[el])
})
})
const char=spliter.sprite()
ctx.strokeText(字符,(碎片位置x+0.1)*dw,(碎片位置y+0.8)*dh)
}
重画
document.querySelector('button')。onclick=\u=>{
splitter.move();redraw()
}
document.querySelector('button.allmoves')。onclick=\u=>{
while(spliter.move()){}
重画
}
canvas{background:#eeeeee;}

走开,老鼠

为了你的生命而行动,老鼠
什么是
颜色(x+1)
?你可能打算写
颜色(x+1,y)
?是的,这就是它的意思,我会编辑它,如果你发布实际的、有效的和完整的代码,你会得到最好的回复。伪代码和代码片段很难处理。看。你说图像2是期望的结果,图像3是实际的结果。你可能是说相反的意思吗?不是说是这样,但它看到了ms like这样可能更有意义(尽管我可能只是误解了)。此外,如上所述,一个独立的例子会有所帮助。(你也许可以打印出来。)