私は画像モザイクの作成に取り組んできました。私のスクリプトは、多数の画像を取得し、サムネイルサイズに縮小してから、それらをタイルとして使用してターゲット画像を概算します。
アプローチは実際にはかなり楽しいです:
すべてのタイルの位置にあるすべての親指の平均二乗誤差を計算します。
最初は、貪欲な配置を使用しました。エラーが最小の親指をタイルに最も適したタイルに配置し、次に次のように配置します。
貪欲の問題は、あまり一致しないかどうかにかかわらず、最も人気のないタイルに最も異なる親指を配置できるようになることです。ここに例を示します: http://williamedwardscoder.tumblr.com/post/84505278488/making-image-mosaics
そのため、スクリプトが中断されるまでランダムスワップを実行します。結果はまったく問題ありません。
2つのタイルのランダムスワップは常に改善されるとは限りませんが、3つ以上のタイルのローテーションにより、全体的な改善、つまりA <-> B
は改善されない可能性がありますが、A -> B -> C -> A
1
五月..
このため、ランダムなタイルを2つ選んで改善されないことがわかった後、タイルの束を選び、そのような回転で3番目のタイルになるかどうかを評価します。 4つのタイルのいずれかのセットが有利に回転できるかどうかなどについては調べません。それは間もなく超高額になるでしょう。
しかし、これには時間がかかります。
より良い、より速いアプローチはありますか?
バウンティの更新
私はさまざまなPython実装と ハンガリー語メソッド Bindingのバインディング)をテストしました。
はるかに高速だったのは純粋なPythonでした https://github.com/xtof-durr/makeSimple/blob/master/Munkres/kuhnMunkres.py
私の直感は、これが最適な答えに近いということです。テストイメージで実行すると、他のすべてのライブラリが結果に同意しましたが、このkuhnMunkres.pyは桁違いに高速でありながら、他の実装が同意したスコアに非常に非常に近づきました。
速度はデータに大きく依存します。モナリザは13分でkuhnMunkres.pyを駆け抜けましたが、スカーレットチェステッドインコは16分かかりました。
結果は、インコのランダムスワップとローテーションとほとんど同じでした。
(左側はkuhnMunkres.py、右側はランダムにスワップします 比較用の元の画像 )
しかし、私がテストしたモナリザの画像では、結果は著しく改善され、実際に彼女は彼女の定義された「笑顔」を輝かせていました:
(左側がkuhnMunkres.py、右側がランダムスワップ)
はい、2つのより速くより速いアプローチがあります。
次に、基になるアルゴリズムを変更せずに、MSEをより視覚的に正確な距離に置き換えることにより、コストを調整できます。
私はそれがNP難しい問題だと確信しています。 「完璧な」ソリューションを見つけるには、あらゆる可能性を徹底的に試さなければならず、それは指数関数的です。
1つのアプローチは、貪欲な適合を使用し、それを改善することです。これは、不適切に配置されたイメージ(最後のイメージの1つ)を取り、それを配置する別の場所を見つけてから、そのイメージを取得して移動することなどが考えられます。 (a)時間が足りなくなったとき(b)適合が「十分に良い」とき、あなたは終わりです。
確率論的要素を導入すると、 シミュレートされたアニーリング アプローチ、または遺伝的アルゴリズムになる可能性があります。おそらく、達成しようとしているのは、エラーを均等に分散させることだけです。これはあなたが既にやっていることに近づいているのではないかと思うので、答えは次のとおりです。正しいアルゴリズムを使用すると、より良い結果をより早く得ることができますが、Nirvanaへの魔法の近道はありません。
はい、これはあなたがすでにやっていることに似ています。ポイントは、魔法の答えを忘れ、2つのアルゴリズムの観点から考えることです。最初に入力し、次に最適化します。
塗りつぶしは、ランダム、利用可能な最高、最初は最高、十分良い、ある種のホットスポットです。
最適化はランダム、最悪の修正、または(私が示唆したように)アニーリングまたは遺伝的アルゴリズムのシミュレーションです。
「良さ」の測定基準とそれに費やして実験する準備ができている時間の長さが必要です。または実際にそれを行った人を見つけます。
最後のタイルが問題である場合は、何とかしてそれらを早い段階で配置するようにしてください;)
1つのアプローチは、一致の上位x%(直感的には33%となる)から最も遠いタイルを見て、それをその最適な一致に配置することです。それはとにかく得ることができる最もよい一致です。
さらに、最悪のタイルに最適な一致を使用しないように選択することもできますが、そのスロットの最適な一致と比較してエラーが最小になるタイルなので、「ダメージコントロール"。
もう1つ覚えておくべきことは、最終的には目で処理する画像を作成することです。したがって、本当に必要なのは、エッジ検出を使用して、画像上のどの位置が最も重要かを判断することです。同様に、画像の非常に周辺で発生することは、効果の品質にとってほとんど価値がありません。これら2つの重みを重ね合わせて、距離の計算に含めます。したがって、発生するジッターは境界に向かって引き寄せられ、エッジから離れるので、妨害は大幅に少なくなります。
また、エッジ検出が適切な場合、最初のy%を貪欲に(おそらく、タイルの「エッジ」の特定のしきい値を下回るまで)、「ホットスポット」が本当にうまく処理されるようにすることができます。残りは「ダメージコントロール」に切り替えます。