Qual é o melhor algoritmo de "preenchimento de balde"?


16

Eu sou bastante novo no processamento de imagens e atualmente estou trabalhando em um aplicativo semelhante a tinta que apresentará um preenchimento de balde. No entanto, não tenho idéia de qual é o melhor algoritmo para o preenchimento de um balde.

Eu implementei um exemplo que encontrei neste site , no entanto, ele teve problemas de loop infinito quando um usuário tentou preencher uma área que já havia sido preenchida com a mesma cor.

Atualmente, estou contornando esse problema preenchendo esquerda, direita, cima e depois baixo; no entanto, fiz isso para que, uma vez preenchido um pixel à esquerda, ele não possa ser preenchido à direita, o que significa formas como:

Exemplo

não será preenchido corretamente se a ferramenta caçamba for usada no ponto vermelho.

Portanto, espero que alguém conheça um algoritmo ou um link para um que resolva todos esses problemas.

Informações adicionais: Isso será implementado usando Javascript como ferramenta de pintura. Ele será usado on-line utilizando o elemento Canvas.


Esse vetor ou bitmap é baseado? Estou assumindo bitmap pela imagem, mas apenas ter certeza ..
Demian Brecht

1
Eu acho que você implementou algo incorretamente. Passei os olhos pelo documento e, de acordo com os exemplos de imagens, isso deve preencher imagens como a acima. Você copiou e colou o código dele ou reescreveu?
RLH

Pense na travessia do gráfico.
Bwmat

@RLH: copiei e colei o código dele com algumas alterações, a fim de fazê-lo funcionar com minha configuração.
Ivan Ivan

@ Ivan: não comece a procurar por um novo algo antes de resolver seus problemas de "loop infinito". Se você não conseguir consertar isso para uma implementação existente, você definitivamente terá muito mais problemas quando reescrever tudo do zero.
Doc Brown

Respostas:


21

Parece que você está realmente procurando o que é chamado de algoritmo de preenchimento de inundação. Pode ser por isso que você não encontrou muitos exemplos para isso. Existem vários métodos de preenchimento de inundação listados na página da Wikipedia para o algoritmo . Eu recomendo um dos métodos 'recursivos' em fila '.


I highly recommend one of the non-recursive, 'queued' methods.- Você poderia explicar o porquê?
Elfayer 30/03/19

1
@Elfayer Sempre que uma função é chamada (digamos "X ()" chama "Y ()"), os parâmetros e o local da memória da função de origem ("X ()") são armazenados na pilha. Portanto, se você estiver preenchendo um espaço grande e complicado, haverá muitas chamadas de função recursivas. Dependendo do seu compilador e idioma, isso pode levar a estouros de pilha ou consumo excessivo de memória.
boxcartenant

-1

Atualmente, estou fazendo a mesma coisa. No entanto, quando deparei com o problema mencionado, optei por simplesmente encerrar a função se a ferramenta fosse clicada sobre uma área da mesma cor que você está tentando pintar (esse também parece ser o comportamento do ms-paint) .

O método na fila deve ser extremamente intuitivo para qualquer pessoa com alguma experiência em programação.

Se pintar a área ao redor de um ponto da mesma cor da sua pintura for uma preocupação, você poderá:

  • verifique a cor do plano de fundo.
  • procure a borda do ponto da mesma cor em que você clicou.
  • enfileire os pontos circundantes no local.
  • prossiga com a execução normal usando esta (neste caso) fila cheia de pontos brancos.

Se você quiser, pode dar uma olhada no meu código (bastante embaraçoso) aqui .

Está longe de ser rápido, mas funciona bem ...


Por que os votos negativos? :( Eu sei que o método não é particularmente "rápido", mas funciona, e também faz a solução proposta :(
Juan Pablo Alvarez Alfaro

1
é difícil ler este post (parede de texto). Você se importaria de editá -lo em uma forma melhor?
mosquito

2
Seriamente? As pessoas votaram em massa porque era difícil de ler? Por que não optar por editar? Não é como se o conteúdo fosse problemático.
L46kok

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.