Algoritma untuk membuat mosaik gambar - adakah cara yang lebih cepat dari ini?

9

Saya telah bermain dengan membuat mosaik gambar. Script saya mengambil sejumlah besar gambar, mengecilkannya ke ukuran thumbnail dan kemudian menggunakannya sebagai petak untuk memperkirakan gambar target.

Pendekatannya sebenarnya cukup menyenangkan:

Saya menghitung galat kuadrat rata-rata untuk setiap ibu jari di setiap posisi ubin.

Pada awalnya saya hanya menggunakan penempatan serakah: menempatkan ibu jari dengan kesalahan paling sedikit pada ubin yang paling cocok, dan kemudian yang berikutnya dan seterusnya.

Masalahnya dengan serakah adalah pada akhirnya Anda menempatkan ibu jari yang paling berbeda pada ubin yang paling tidak populer, apakah cocok atau tidak. Saya tunjukkan contoh di sini: http://williamedwardscoder.tumblr.com/post/84505278488/making-image-mosaics

Jadi saya kemudian melakukan swap acak sampai skrip terputus. Hasilnya cukup oke.

Pertukaran acak dua ubin tidak selalu merupakan peningkatan, tetapi terkadang rotasi tiga atau lebih ubin menghasilkan peningkatan global yaitu A <-> Bmungkin tidak membaik, tetapi A -> B -> C -> A1mungkin ..

Untuk alasan ini, setelah memilih dua ubin acak dan menemukan mereka tidak membaik, saya memilih sekelompok ubin untuk mengevaluasi apakah mereka bisa menjadi ubin ketiga dalam rotasi seperti itu. Saya tidak mengeksplorasi apakah set empat ubin dapat diputar menguntungkan, dan sebagainya; itu akan menjadi super mahal segera.

Tapi ini butuh waktu .. Banyak waktu!

Apakah ada pendekatan yang lebih baik dan lebih cepat?


Pembaruan hadiah

Saya menguji berbagai implementasi Python dan binding dari Metode Hungaria .

Sejauh ini yang tercepat adalah Python murni https://github.com/xtof-durr/makeSimple/blob/master/Munkres/kuhnMunkres.py

Firasat saya adalah bahwa ini mendekati jawaban optimal; ketika dijalankan pada gambar uji, semua perpustakaan lain menyetujui hasil tetapi ini kuhnMunkres.py, sementara menjadi pesanan besarnya lebih cepat, hanya menjadi sangat sangat dekat dengan skor implementasi yang disepakati.

Kecepatan sangat bergantung pada data; Mona Lisa bergegas melewati kuhnMunkres.py dalam 13 menit, tetapi Parkit Scarlet Chested membutuhkan waktu 16 menit.

Hasilnya hampir sama dengan swap dan rotasi acak untuk parkit:

masukkan deskripsi gambar di sinimasukkan deskripsi gambar di sini

(kuhnMunkres.py di sebelah kiri, swap acak di sebelah kanan; gambar asli untuk perbandingan )

Namun, untuk gambar Mona Lisa yang saya uji, hasilnya terlihat lebih baik dan dia benar-benar membuat 'senyuman' definisinya bersinar melalui:

masukkan deskripsi gambar di sinimasukkan deskripsi gambar di sini

(kuhnMunkres.py di sebelah kiri, swap acak di sebelah kanan)

Akan
sumber
1
Terkait ... ish. Pada transformasi langit-langit Codegolf memiliki masalah yang sama.
1
Dan serangkaian gambar terkait lainnya adalah allRGB di mana setiap gambar (meskipun itu tidak memberi Anda terlalu banyak petunjuk tentang cara melakukannya ... hanya saja ada area lain di mana masalah ini telah didekati).
1
Saya mengalami masalah ini dengan pembuat mosaik beberapa tahun yang lalu. Baris alasan saya dulu dan sekarang adalah bahwa masalahnya bukan pada algoritma Anda (bagian MSE) melainkan dengan ukuran terbatas palet gambar input Anda. Tidak memiliki satu miliar gambar untuk dikerjakan, saya memalsukannya dengan memungkinkan gambar untuk digunakan kembali setelah beberapa waktu. Namun, jika Anda ingin tetap menggunakan pendekatan Anda, mungkin baik untuk melakukan operan pertama untuk kecocokan "baik" dan kemudian memperlakukan sisa gambar sebagai acak (atau acak-ish) - dengan set input terbatas yang hanya Anda miliki begitu banyak pilihan.
J Trana
@MichaelT, terima kasih atas tautannya yang bagus :) Codegolf khususnya sangat menarik. Saya menemukan solusi terpilih-terbaik menggunakan swap acak (bukan rotasi acak) dan mungkin berjalan cukup lama ...
Will
1
Datang ke ini setelah Anda memilih jawaban dan memberikan hadiah. Pendekatan yang berbeda akan memperlakukan ini sebagai masalah Annealing Simulasi . Anda bisa menggunakan SA sebagai salah satu tahapan dari pipa solusi Anda.
andy256

Jawaban:

3

Ya, ada dua pendekatan yang lebih baik dan lebih cepat.

  • Masalah yang lebih sederhana: untuk setiap ubin, pilih ibu jari terbaik (dengan kemungkinan duplikasi). Oke, itu curang, tetapi hanya bisa menghasilkan hasil visual yang lebih baik.
  • Pilihan Anda secara algoritmik lebih menarik, dan bermuara pada "masalah penetapan linier", dengan asumsi Anda menggunakan MSE sebagai biaya kecocokan yang jumlahnya harus minimal. Masalah seperti itu dapat diselesaikan dalam waktu polinomial, misalnya melalui "Metode Hongaria"

Kemudian, Anda dapat menyesuaikan biaya dengan mengganti MSE dengan jarak yang lebih akurat secara visual, tanpa mengubah algoritma yang mendasarinya.

YvesgereY
sumber
Terima kasih! Metode LAP dan Hongaria adalah petunjuk yang saya butuhkan! Perbarui dengan hasil yang dipertanyakan.
Will
3

Saya cukup yakin itu masalah NP-hard. Untuk menemukan solusi 'sempurna' Anda harus mencoba setiap kemungkinan secara menyeluruh, dan itu eksponensial.

Salah satu pendekatan akan menggunakan fit serakah dan kemudian mencoba untuk memperbaikinya. Itu bisa dengan mengambil gambar yang ditempatkan dengan buruk (salah satu yang terakhir) dan menemukan tempat lain untuk meletakkannya, kemudian mengambil gambar itu dan memindahkannya dan seterusnya. Anda selesai ketika Anda (a) kehabisan waktu (b) kecocokannya adalah 'cukup baik'.

Jika Anda memperkenalkan elemen probabilistik, ia mungkin menghasilkan pendekatan anil simulasi , atau algoritma genetika. Mungkin yang Anda coba capai adalah menyebarkan kesalahan secara merata. Saya menduga ini semakin dekat dengan apa yang sudah Anda lakukan sehingga jawabannya adalah: dengan algoritma yang tepat Anda bisa mendapatkan hasil yang lebih baik lebih cepat tetapi tidak ada jalan pintas ajaib ke Nirvana.


Ya, ini mirip dengan apa yang sudah Anda lakukan. Intinya adalah untuk melupakan jawaban ajaib dan berpikir dalam hal 2 algoritma: pertama isi, lalu optimalkan.

Isi dapat berupa: acak, tersedia terbaik, terbaik pertama, cukup baik, semacam hot spot.

Optimalisasi bisa acak, memperbaiki yang terburuk, atau (seperti yang saya sarankan) disimulasikan annealing atau algoritma genetika.

Anda memerlukan metrik 'kebaikan' dan jumlah waktu yang siap Anda habiskan untuk itu dan hanya bereksperimen. Atau temukan seseorang yang benar-benar melakukannya.

david.pfx
sumber
Anda menggambarkan dengan tepat pendekatan yang dijelaskan dalam pertanyaan ...?
Will
1

Jika ubin terakhir adalah masalah Anda, Anda harus mencoba menempatkannya sejak awal, entah bagaimana;)

Salah satu pendekatannya adalah dengan melihat ubin yang paling jauh dari x% teratas pertandingannya (secara intuitif saya menggunakan 33%) dan menempatkannya pada pertandingan terbaiknya. Itu adalah pertandingan terbaik yang bisa didapat.

Selain itu, Anda dapat memilih untuk tidak menggunakan kecocokan terbaik untuk ubin terburuk, tetapi pencocokan yang paling sedikit menghasilkan kesalahan dibandingkan dengan pencocokan terbaik untuk slot itu, sehingga Anda tidak sepenuhnya membuang pencocokan terbaik Anda demi " kontrol kerusakan ".

Hal lain yang perlu diingat adalah bahwa pada akhirnya Anda menghasilkan gambar untuk diproses oleh mata. Jadi yang Anda inginkan adalah menggunakan deteksi tepi untuk menentukan posisi mana pada gambar Anda yang paling penting. Demikian pula, apa yang terjadi pada bagian paling tepi dari gambar sedikit nilainya terhadap kualitas efek. Taruh dua bobot ini dan sertakan dalam perhitungan jarak Anda. Kegelisahan yang Anda dapatkan karenanya harus condong ke perbatasan dan menjauhi tepi, sehingga mengganggu jauh lebih sedikit.

Juga dengan deteksi tepi di tempat, Anda mungkin ingin menempatkan y% pertama dengan rakus (mungkin sampai Anda turun di bawah ambang batas "kegelisahan" di ubin kiri), sehingga "hot spot" ditangani dengan sangat baik, dan kemudian beralih ke "kontrol kerusakan" untuk sisanya.

back2dos
sumber