Qual è il miglior algoritmo "bucket-fill"?


16

Sono abbastanza nuovo nell'elaborazione delle immagini e attualmente sto lavorando a un'applicazione simile a una vernice che includerà un riempimento a secchiello. Tuttavia, non ho idea di quale sia l'algoritmo migliore per un bucket-fill.

Ho implementato un esempio che ho trovato da questo sito , tuttavia, si sono imbattuti in infiniti problemi di loop quando un utente ha cercato di riempire a secchio un'area che era già stata riempita a secchio con lo stesso colore.

Attualmente sto risolvendo il problema compilando sinistra, destra, su e poi giù; tuttavia, l'ho fatto in modo che una volta che un pixel è stato riempito a sinistra, non può riempire a destra, il che significa forme come:

Esempio

non verrà riempito correttamente se lo strumento secchio viene utilizzato nel punto rosso.

Pertanto, spero che qualcuno conosca un algoritmo o un collegamento a uno che risolverà tutti questi problemi.

Informazioni aggiuntive: questo sarà implementato usando Javascript come strumento di disegno. Verrà utilizzato online utilizzando l'elemento Canvas.


Questo vettore o bitmap è basato? Sto assumendo bitmap dall'immagine, ma sto solo assicurandomi ...
Demian Brecht,

1
Penso che tu abbia implementato qualcosa in modo errato. Ho scremato il documento e secondo gli esempi di immagine, questo dovrebbe riempire immagini come quella sopra. Hai copiato e incollato il suo codice o l'hai riscritto?
RLH,

Pensa all'attraversamento del grafico.
Bwmat,

@RLH: copio e incollo il suo codice con alcune modifiche per farlo funzionare con il mio setup.
Ivan,

@Ivan: non iniziare a cercare un nuovo algo prima di aver risolto i problemi del "ciclo infinito". Se non riesci nemmeno a risolverlo per un'implementazione esistente, avrai sicuramente molti più problemi quando riscrivi il tutto da zero.
Doc Brown,

Risposte:


21

Sembra che tu stia effettivamente cercando quello che è chiamato un algoritmo Flood Fill. Questo potrebbe essere il motivo per cui non hai trovato tonnellate di esempi per questo. Esistono diversi metodi Flood Fill elencati nella pagina Wikipedia per l'algoritmo . Consiglio vivamente uno dei metodi "in coda" non ricorsivi.


I highly recommend one of the non-recursive, 'queued' methods.- Potresti spiegare perché?
Elfayer,

1
@Elfayer Ogni volta che viene chiamata una funzione (ad esempio "X ()" ha una chiamata a "Y ()"), i parametri e la posizione della memoria dalla funzione di origine ("X ()") vengono memorizzati nello stack. Quindi, se stai riempiendo uno spazio ampio e complicato, allora ci saranno molte chiamate di funzioni ricorsive. A seconda del compilatore e della lingua, ciò può causare overflow dello stack o consumo eccessivo di memoria.
boxcartenant

-1

Attualmente sto facendo la stessa cosa. Tuttavia, quando mi sono imbattuto nel problema che hai sottolineato, ho optato per la semplice fine della funzione se lo strumento è stato cliccato su un'area dello stesso colore che stai cercando di dipingere (anche questo sembra essere il comportamento di ms-paint) .

Il metodo in coda dovrebbe essere estremamente intuitivo per chiunque abbia qualche esperienza di programmazione.

Se dipingere l'area che circonda una macchia dello stesso colore della tua vernice è un problema, puoi:

  • controlla il colore di sfondo.
  • cerca il bordo del punto dello stesso colore in cui hai fatto clic.
  • mettere in coda i punti circostanti sul posto.
  • procedere con la normale esecuzione usando questa (in questo caso) coda piena di punti bianchi.

Se lo desideri, puoi dare un'occhiata al mio codice (abbastanza imbarazzante) qui .

È lungi dall'essere veloce ma funziona bene ...


Perché i downvotes? :( So che il metodo non è particolarmente "veloce", ma funziona e fa anche la soluzione proposta :(
Juan Pablo Alvarez Alfaro

1
questo post è piuttosto difficile da leggere (wall of text). Ti dispiacerebbe modificarlo in una forma migliore?
moscerino

2
Sul serio? Le persone hanno votato in massa perché era difficile da leggere? Perché non scegliere di modificare? Non è che il contenuto sia problematico.
l46kok

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.