Algorithmen zur Erstellung von Bildmosaiken - gibt es einen schnelleren Weg als diesen?


9

Ich habe mit der Herstellung von Bildmosaiken gespielt. Mein Skript nimmt eine große Anzahl von Bildern auf, verkleinert sie auf die Größe der Miniaturansichten und verwendet sie dann als Kacheln, um ein Zielbild zu approximieren.

Der Ansatz ist eigentlich recht erfreulich:

Ich berechne den mittleren quadratischen Fehler für jeden Daumen in jeder Kachelposition.

Zuerst habe ich nur eine gierige Platzierung verwendet: Legen Sie den Daumen mit dem geringsten Fehler auf die Kachel, die am besten passt, und dann die nächste und so weiter.

Das Problem mit gierig ist, dass Sie schließlich die unterschiedlichsten Daumen auf die am wenigsten beliebten Kacheln legen, unabhängig davon, ob sie genau übereinstimmen oder nicht. Ich zeige hier Beispiele: http://williamedwardscoder.tumblr.com/post/84505278488/making-image-mosaics

Also mache ich dann zufällige Swaps, bis das Skript unterbrochen wird. Die Ergebnisse sind ganz in Ordnung.

Ein zufälliger Austausch von zwei Kacheln ist nicht immer eine Verbesserung, aber manchmal führt eine Drehung von drei oder mehr Kacheln zu einer globalen Verbesserung, dh A <-> Bmöglicherweise nicht verbessert, aber A -> B -> C -> A1möglicherweise.

Aus diesem Grund wähle ich, nachdem ich zwei zufällige Kacheln ausgewählt und festgestellt habe, dass sie sich nicht verbessern, eine Reihe von Kacheln aus, um zu bewerten, ob sie die dritte Kachel in einer solchen Drehung sein können. Ich untersuche nicht, ob ein Satz von vier Kacheln gewinnbringend gedreht werden kann, und so weiter. das wäre sehr bald super teuer.

Aber das braucht Zeit. Viel Zeit!

Gibt es einen besseren und schnelleren Ansatz?


Kopfgeld-Update

Ich habe verschiedene Python-Implementierungen und -Bindungen der ungarischen Methode getestet .

Das mit Abstand schnellste war das reine Python https://github.com/xtof-durr/makeSimple/blob/master/Munkres/kuhnMunkres.py

Meine Vermutung ist, dass dies ungefähr die optimale Antwort ist; Bei der Ausführung eines Testbilds waren sich alle anderen Bibliotheken über das Ergebnis einig, aber diese kuhnMunkres.py war zwar um Größenordnungen schneller, kam aber nur sehr nahe an die Punktzahl heran, auf die sich die anderen Implementierungen geeinigt hatten.

Die Geschwindigkeit ist sehr datenabhängig. Mona Lisa eilte in 13 Minuten durch kuhnMunkres.py, aber der Scarlet Chested Parakeet brauchte 16 Minuten.

Die Ergebnisse waren ähnlich wie bei zufälligen Swaps und Rotationen für den Sittich:

Geben Sie hier die Bildbeschreibung einGeben Sie hier die Bildbeschreibung ein

(kuhnMunkres.py links, zufällige Swaps rechts; Originalbild zum Vergleich )

Für das Mona Lisa-Bild, mit dem ich getestet habe, wurden die Ergebnisse jedoch merklich verbessert, und ihr klares "Lächeln" schien tatsächlich durch:

Geben Sie hier die Bildbeschreibung einGeben Sie hier die Bildbeschreibung ein

(kuhnMunkres.py links, zufällige Swaps rechts)


1
Verwandte ... ish. Am Codegolf Gaumen Transformations ähnliche Probleme hatten.

1
Und eine andere ähnliche Reihe von Bildern ist allRGB wobei jedes Bild (obwohl das nicht geben Sie zu viel von einem Hauch , wie es zu tun ... nur , dass es gibt einen anderen Bereich , in dem dieses Problem angegangen wurde).

1
Ich bin vor einigen Jahren mit einem Mosaikhersteller auf dieses Problem gestoßen. Meine Argumentation damals und heute ist, dass das Problem nicht so sehr bei Ihrem Algorithmus (dem MSE-Teil) liegt, sondern bei der begrenzten Größe Ihrer Eingabebildpalette. Da ich nicht mit einer Milliarde Bildern arbeiten konnte, habe ich es gefälscht, indem ich zugelassen habe, dass ein Bild nach einiger Zeit wiederverwendet wird. Wenn Sie jedoch Ihren Ansatz beibehalten möchten, kann es sinnvoll sein, einen ersten Durchgang für "gute" Anpassungen durchzuführen und dann den Rest der Bilder als zufällig (oder zufällig) zu behandeln - mit einem begrenzten Eingabesatz, den Sie nur haben so viele Möglichkeiten.
J Trana

@MichaelT danke für diesen exzellenten Link :) Der Codegolf ist besonders faszinierend. Ich finde, die besten Lösungen verwenden zufällige Swaps (keine zufälligen Rotationen) und laufen vermutlich eine ganze Weile ...
Will

1
Kommen Sie dazu, nachdem Sie eine Antwort ausgewählt und ein Kopfgeld vergeben haben. Ein anderer Ansatz wäre, dies als simuliertes Glühproblem zu behandeln . Sie können SA als eine der Phasen Ihrer Lösungspipeline verwenden.
andy256

Antworten:


3

Ja, es gibt zwei bessere und schnellere Ansätze.

  • Einfacheres Problem: Wählen Sie für jede Kachel den besten Daumen (mit möglicher Duplizierung). Ok, das ist Betrug, kann aber nur zu einem besseren visuellen Ergebnis führen.
  • Ihr Take ist algorithmisch interessanter und läuft auf das "lineare Zuweisungsproblem" hinaus, vorausgesetzt, Sie nehmen MSE als Match-Kosten, deren Summe minimal sein muss. Ein solches Problem kann in Polynomzeit gelöst werden, beispielsweise über die "ungarische Methode".

Anschließend können Sie Ihre Kosten anpassen, indem Sie MSE durch eine visuell genauere Entfernung ersetzen, ohne den zugrunde liegenden Algorithmus zu ändern.


Vielen Dank! LAP und die ungarische Methode waren die Leads, die ich brauchte! Update mit fraglichen Ergebnissen.
Wird

3

Ich bin mir ziemlich sicher, dass dies ein NP-schwieriges Problem ist. Um eine „perfekte“ Lösung zu finden, müssen Sie jede Möglichkeit gründlich ausprobieren, und das ist exponentiell.

Ein Ansatz wäre, die gierige Passform zu verwenden und dann zu versuchen, sie zu verbessern. Das könnte sein, indem Sie ein schlecht platziertes Bild (eines der letzten) aufnehmen und einen anderen Platz finden, um es zu platzieren, dann dieses Bild aufnehmen und es verschieben und so weiter. Sie sind fertig, wenn Ihnen (a) die Zeit ausgeht (b) die Passform "gut genug" ist.

Wenn Sie ein probabilistisches Element einführen, kann dies zu einem simulierten Annealing- Ansatz oder einem genetischen Algorithmus führen. Vielleicht versuchen Sie nur, die Fehler gleichmäßig zu verteilen. Ich vermute, dass dies dem nahe kommt, was Sie bereits tun. Die Antwort lautet: Mit dem richtigen Algorithmus erzielen Sie möglicherweise schneller ein besseres Ergebnis, aber es gibt keine magische Abkürzung zu Nirvana.


Ja, das ähnelt dem, was Sie bereits tun. Es geht darum, eine magische Antwort zu vergessen und in zwei Algorithmen zu denken: zuerst füllen, dann optimieren.

Die Füllung könnte sein: zufällig, am besten verfügbar, zuerst am besten, gut genug, eine Art Hot Spot.

Die Optimierung kann zufällig erfolgen, das Schlimmste beheben oder (wie ich vorgeschlagen habe) einen simulierten Annealing- oder genetischen Algorithmus.

Sie benötigen eine Metrik für "Güte" und eine Menge Zeit, die Sie bereit sind, damit zu verbringen und einfach zu experimentieren. Oder jemanden finden, der es tatsächlich getan hat.


Sie beschreiben genau den in der Frage beschriebenen Ansatz ...?
Wird

1

Wenn die letzten Kacheln dein Problem sind, solltest du versuchen, sie irgendwie früh zu platzieren;)

Ein Ansatz wäre, die Kachel zu betrachten, die am weitesten von den oberen x% ihrer Übereinstimmungen entfernt ist (intuitiv würde ich mit 33% gehen) und diese auf die beste Übereinstimmung zu setzen. Das ist das beste Match, das es sowieso bekommen kann.

Außerdem könnten Sie wählen, nicht die beste Übereinstimmung für die schlechteste Kachel zu verwenden, sondern diejenige, bei der der geringste Fehler im Vergleich zur besten Übereinstimmung für diesen Slot auftritt, damit Sie Ihre besten Übereinstimmungen nicht vollständig wegwerfen, um " Schadenskontrolle".

Eine andere Sache, die Sie beachten sollten, ist, dass Sie am Ende ein Bild produzieren, das von einem Auge verarbeitet werden soll. Was Sie also wirklich wollen, ist eine Kantenerkennung, um zu bestimmen, welche Positionen auf Ihrem Bild am wichtigsten sind. In ähnlicher Weise ist das, was am äußersten Rand des Bildes geschieht, für die Qualität des Effekts von geringem Wert. Überlagern Sie diese beiden Gewichte und nehmen Sie sie in Ihre Entfernungsberechnung auf. Jeder Jitter, den Sie bekommen, sollte sich daher zum Rand hin und von den Rändern weg bewegen und so viel weniger stören.

Auch wenn die Kantenerkennung aktiviert ist, möchten Sie möglicherweise das erste y% gierig platzieren (möglicherweise bis Sie eine bestimmte Schwelle für "Kanten" in den Kacheln links unterschreiten), damit die "Hot Spots" wirklich gut behandelt werden. und wechseln Sie dann für den Rest zu "Schadenskontrolle".

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.