Algoritmi per realizzare mosaici di immagini: esiste un modo più rapido di questo?


9

Ho giocato con la creazione di mosaici di immagini. La mia sceneggiatura prende un gran numero di immagini, le ridimensiona in base alle dimensioni dell'anteprima e quindi le utilizza come riquadri per approssimare un'immagine di destinazione.

L'approccio è in realtà abbastanza piacevole:

Calcolo l'errore quadratico medio per ogni pollice in ogni posizione della piastrella.

All'inizio ho appena usato un posizionamento avido: metti il ​​pollice con il minimo errore sulla piastrella che meglio si adatta, e poi il successivo e così via.

Il problema con l'avido è che alla fine ti lascia posizionare i pollici più diversi sulle tessere meno popolari, indipendentemente dal fatto che corrispondano o meno. Mostro esempi qui: http://williamedwardscoder.tumblr.com/post/84505278488/making-image-mosaics

Quindi eseguo scambi casuali fino a quando lo script non viene interrotto. I risultati sono abbastanza soddisfacenti.

Uno scambio casuale di due tessere non è sempre un miglioramento, ma a volte una rotazione di tre o più tessere si traduce in un miglioramento globale, cioè A <-> Bpotrebbe non migliorare, ma A -> B -> C -> A1potrebbe ..

Per questo motivo, dopo aver scelto due tessere casuali e aver scoperto che non migliorano, scelgo un gruppo di tessere per valutare se possono essere la terza tessera in tale rotazione. Non esploro se una serie di quattro tessere può essere ruotata proficuamente, e così via; sarebbe molto costoso molto presto.

Ma questo richiede tempo .. Un sacco di tempo!

Esiste un approccio migliore e più veloce?


Aggiornamento di Bounty

Ho testato varie implementazioni e collegamenti Python del metodo ungherese .

Di gran lunga il più veloce è stato il puro Python https://github.com/xtof-durr/makeSimple/blob/master/Munkres/kuhnMunkres.py

La mia impressione è che ciò approssima la risposta ottimale; quando eseguito su un'immagine di prova, tutte le altre biblioteche concordavano sul risultato ma questo kuhnMunkres.py, pur essendo ordini di grandezza più veloci, si avvicinava molto molto al punteggio ottenuto dalle altre implementazioni concordate.

La velocità dipende molto dai dati; Mona Lisa si è precipitata attraverso kuhnMunkres.py in 13 minuti, ma il Parrocchetto di Petto Scarlatto ha impiegato 16 minuti.

I risultati erano quasi gli stessi degli scambi e delle rotazioni casuali per il Parakeet:

inserisci qui la descrizione dell'immagineinserisci qui la descrizione dell'immagine

(kuhnMunkres.py a sinistra, scambi casuali a destra; immagine originale per il confronto )

Tuttavia, per l'immagine di Mona Lisa con cui ho provato, i risultati sono stati notevolmente migliorati e in realtà ha fatto brillare il suo "sorriso" definito:

inserisci qui la descrizione dell'immagineinserisci qui la descrizione dell'immagine

(kuhnMunkres.py a sinistra, scambi casuali a destra)


1
Related ... ish. Sul palato di Codegolf la trasformazione aveva problemi simili.

1
E un altro set correlato di immagini è tuttoRGB in cui ogni immagine (anche se questo non ti dà troppo un indizio su come farlo ... solo che c'è un'altra area in cui questo problema è stato affrontato).

1
Ho incontrato questo problema con un creatore di mosaico alcuni anni fa. Il mio ragionamento allora e ora è che il problema non è tanto con il tuo algoritmo (la parte MSE) ma piuttosto con le dimensioni limitate della tua tavolozza di immagini di input. Non avendo un miliardo di immagini con cui lavorare, l'ho falsificato consentendo di riutilizzare un'immagine dopo un certo periodo di tempo. Tuttavia, se vuoi mantenere il tuo approccio, può essere utile fare un primo passaggio per adattamenti "buoni" e quindi trattare il resto delle immagini come casuali (o casuali) - con un set di input limitato hai solo così tante scelte.
J Trana,

@MichaelT grazie per l'ottimo link :) Il codegolf è particolarmente affascinante. Trovo che le migliori soluzioni votate stiano utilizzando scambi casuali (non rotazioni casuali) e presumibilmente funzionino per un bel po '...
Will

1
Venendo a questo dopo aver selezionato una risposta e assegnato una taglia. Un approccio diverso sarebbe quello di trattare questo come un problema di ricottura simulata . È possibile utilizzare SA come una delle fasi della pipeline della soluzione.
andy256,

Risposte:


3

Sì, ci sono due approcci migliori e più veloci.

  • Problema più semplice: per ogni riquadro, scegli il pollice migliore (con possibile duplicazione). Ok, questo è barare, ma può solo portare a un migliore risultato visivo.
  • Il tuo introito è algoritmicamente più interessante e si riduce al "problema di assegnazione lineare", supponendo che tu prenda MSE come costo della partita la cui somma deve essere minima. Tale problema può essere risolto in tempi polinomiali, ad esempio tramite il "Metodo ungherese"

Quindi, è possibile regolare i costi sostituendo MSE con una distanza visivamente più accurata, senza modificare l'algoritmo sottostante.


Grazie! LAP e il metodo ungherese erano i cavi di cui avevo bisogno! Aggiornamento con risultati in questione.
Sarà il

3

Sono ragionevolmente sicuro che sia un problema NP-difficile. Per trovare una soluzione 'perfetta' devi provare ogni possibilità in modo esaustivo, ed è esponenziale.

Un approccio sarebbe quello di utilizzare la vestibilità golosa e quindi provare a migliorarla. Potrebbe essere prendendo un'immagine mal posizionata (una delle ultime) e trovando un altro posto dove metterla, quindi prendendo quell'immagine e spostandola e così via. Hai finito quando (a) esaurisci il tempo (b) l'adattamento è 'abbastanza buono'.

Se si introduce un elemento probabilistico, ciò potrebbe produrre un approccio di ricottura simulato o un algoritmo genetico. Forse tutto ciò che stai cercando di ottenere è diffondere gli errori in modo uniforme. Ho il sospetto che questo si stia avvicinando a quello che stai già facendo, quindi la risposta è: con l'algoritmo giusto potresti ottenere un risultato migliore più velocemente ma non c'è scorciatoia magica per Nirvana.


Sì, questo è simile a quello che stai già facendo. Il punto è dimenticare una risposta magica e pensare in termini di 2 algoritmi: prima riempi, poi ottimizza.

Il riempimento potrebbe essere: casuale, migliore disponibile, primo migliore, abbastanza buono, una sorta di hot spot.

L'ottimizzazione potrebbe essere casuale, correggere il peggio o (come ho suggerito) un algoritmo di ricottura o genetico simulato.

Hai bisogno di una metrica di "bontà" e di una quantità di tempo che sei disposto a spendere per sperimentare. O trova qualcuno che l'abbia effettivamente fatto.


Descrivi esattamente l'approccio descritto nella domanda ...?
Sarà il

1

Se le ultime tessere sono il tuo problema, dovresti provare a posizionarle presto, in qualche modo;)

Un approccio sarebbe quello di guardare la tessera che è la più lontana dal massimo x% delle sue partite (intuitivamente andrei con il 33%) e posizionarla sulla sua migliore corrispondenza. Questa è la migliore corrispondenza che può ottenere comunque.

Inoltre potresti scegliere di non usare la migliore corrispondenza per la peggiore tessera, ma quella in cui introduce il minor errore rispetto alla migliore corrispondenza per quella slot, in modo da non buttare via completamente le tue migliori partite per amore di " controllo dei danni".

Un'altra cosa da tenere a mente è che alla fine stai producendo un'immagine da elaborare con un occhio. Quindi quello che vuoi davvero è usare un po 'di rilevamento dei bordi per determinare quali posizioni sulla tua immagine sono più importanti. Allo stesso modo, ciò che accade alla periferia dell'immagine è di scarso valore per la qualità dell'effetto. Sovrapponi questi due pesi e includili nel calcolo della distanza. Qualsiasi jitter che si ottiene dovrebbe quindi gravitare verso il bordo e lontano dai bordi, disturbando molto meno.

Inoltre, con la rilevazione del bordo in atto, potresti voler posizionare il primo y% avidamente (forse fino a quando non scendi sotto una certa soglia di "spigolosità" nelle tessere a sinistra), in modo che i "punti caldi" vengano gestiti in modo molto gradevole, e poi passa al "controllo dei danni" per il resto.

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.