Tulis program yang menggunakan gambar RGB warna asli I , jumlah garis maksimum untuk menggambar L , dan minimum m dan panjang M maksimum setiap baris. Output gambar O yang terlihat sebanyak mungkin seperti saya dan diambil menggunakan L atau garis lurus sedikit, yang semuanya memiliki panjang Euclidean antara m dan M .
Setiap baris harus satu warna solid, memiliki kedua titik akhir dalam batas O , dan digambar menggunakan algoritma garis Bresenham (yang sebagian besar perpustakaan grafis akan lakukan untuk Anda). Garis individual hanya dapat setebal 1-pixel.
Semua baris, bahkan yang panjangnya 0, harus mengambil setidaknya satu piksel. Garis dapat ditarik di atas satu sama lain.
Sebelum menggambar garis apa pun, Anda dapat menginisialisasi latar belakang O ke warna solid apa pun (yang mungkin bergantung pada I ).
Detail
- O harus memiliki dimensi yang sama dengan saya .
- L akan selalu menjadi bilangan bulat tidak negatif. Ini mungkin lebih besar daripada daerah saya .
- m dan M adalah angka floating point yang tidak negatif dengan M > = m . Jarak antara dua piksel adalah jarak Euclidean di antara pusat-pusatnya. Jika jarak ini kurang dari m atau lebih besar dari M , maka garis di antara piksel tersebut tidak diperbolehkan.
- Garis-garis tidak boleh antialiased.
- Opacity dan alpha tidak boleh digunakan.
- Program Anda seharusnya tidak perlu lebih dari satu jam untuk berjalan di komputer modern yang layak pada gambar dengan kurang dari satu juta piksel dan L kurang dari 10.000.
Gambar Uji
Anda tentu saja harus menunjukkan kepada kami gambar-gambar keluaran Anda yang paling akurat atau menarik (yang saya perkirakan akan terjadi ketika L adalah antara 5% dan 25% dari jumlah piksel dalam I , dan m dan M sekitar sepersepuluh dari ukuran diagonal).
Berikut adalah beberapa gambar uji (klik untuk dokumen asli). Anda juga dapat memposting sendiri.
Gambar yang lebih sederhana:
Ini adalah kontes popularitas. Kiriman terpilih tertinggi menang.
Catatan
- Mungkin bermanfaat untuk membiarkan L diturunkan dari persentase total piksel dalam I serta nilai absolut. misalnya
>>> imageliner I=img.png L=50% m=10 M=20
akan menjadi hal yang sama seperti>>> imageliner I=img.png L=32 m=10 M=20
jikaimg.png
gambar berukuran 8 x 8 piksel. Hal serupa dapat dilakukan untuk m dan M . Ini tidak wajib. - Karena garis tidak bisa keluar dari batas, garis terpanjang yang mungkin akan menjadi panjang diagonal dari saya . Memiliki M lebih tinggi dari ini seharusnya tidak merusak apa pun.
- Secara alami, jika m adalah 0 dan L lebih besar dari atau sama dengan jumlah piksel dalam I , O dapat identik dengan I dengan memiliki panjang 0 "garis" di setiap lokasi piksel. Perilaku ini tidak diperlukan.
- Boleh dibilang, mereproduksi bentuk I lebih penting daripada mereproduksi warna. Anda mungkin ingin melihat ke deteksi tepi .
sumber
Jawaban:
C ++ - garis agak acak dan kemudian beberapa
Pertama beberapa garis acak
Langkah pertama dari algoritma secara acak menghasilkan garis, mengambil gambar target rata-rata dari piksel di sepanjang ini, dan kemudian menghitung jika kuadrat persegi dari jarak ruang rgb dari semua piksel akan lebih rendah jika kita akan melukis garis baru (dan cat saja, jika ada). Warna garis baru untuk ini dipilih sebagai rata-rata saluran bijaksana dari nilai rgb, dengan tambahan acak -15 / + 15.
Hal-hal yang saya perhatikan dan memengaruhi implementasinya:
Saya bereksperimen dengan beberapa angka, dan memilih
L=0.3*pixel_count(I)
dan pergim=10
danM=50
. Ini akan menghasilkan hasil yang bagus mulai sekitar0.25
untuk0.26
untuk jumlah baris, tapi aku memilih 0,3 untuk memiliki lebih banyak ruang untuk rincian akurat.Untuk gambar gerbang emas berukuran penuh, ini menghasilkan 235929 garis untuk melukis (yang butuh 13 detik kekalahan di sini). Perhatikan bahwa semua gambar di sini ditampilkan dalam ukuran yang diperkecil dan Anda harus membukanya di tab baru / unduh untuk melihat resolusi penuh.
Hapus yang tidak layak
Langkah selanjutnya agak mahal (untuk jalur 235k butuh waktu sekitar satu jam, tetapi itu harus baik dalam "satu jam untuk jalur 10k pada persyaratan waktu 1 megapiksel"), tetapi juga agak mengejutkan. Saya melewati semua garis yang sebelumnya dicat, dan menghapus yang tidak membuat gambar lebih baik. Ini membuat saya dalam menjalankan ini dengan hanya 97347 baris yang menghasilkan gambar berikut:
Anda mungkin perlu mengunduh dan membandingkannya di penampil gambar yang sesuai untuk melihat sebagian besar perbedaan.
dan mulai lagi dari awal
Sekarang saya memiliki banyak garis yang bisa saya lukis lagi hingga total 235929 lagi. Tidak banyak bicara, jadi di sini adalah gambar:
analisis singkat
Seluruh prosedur tampaknya berfungsi seperti filter buram yang peka terhadap kontras lokal dan ukuran objek. Tetapi juga menarik untuk melihat di mana garis-garisnya dicat, sehingga program merekam ini juga (Untuk setiap baris, warna piksel akan dibuat satu langkah lebih putih, pada akhirnya kontras dimaksimalkan). Berikut adalah yang sesuai dengan tiga warna di atas.
animasi
Dan karena kita semua menyukai animasi, berikut adalah beberapa animasi gif dari seluruh proses untuk gambar golden gate yang lebih kecil. Perhatikan bahwa ada dithering yang signifikan karena format gif (dan karena pencipta format file animasi true color dan pabrikan browser sedang berperang melawan ego mereka, tidak ada format standar untuk animasi warna yang sebenarnya, kalau tidak saya bisa menambahkan .mng atau serupa ).
Lebih lagi
Seperti yang diminta, berikut adalah beberapa hasil dari gambar lain (sekali lagi Anda mungkin perlu membukanya di tab baru untuk tidak menurunkannya)
Pikiran masa depan
Bermain-main dengan kode dapat memberikan beberapa variasi yang menarik.
Kode
Ini hanyalah dua fungsi utama yang bermanfaat, seluruh kode tidak cocok di sini dan dapat ditemukan di http://ideone.com/Z2P6Ls
bmp
Kelas - kelasraw
danraw_line
fungsinya masing-masing mengakses piksel dan garis dalam sebuah objek yang dapat ditulis ke format bmp (Itu hanya beberapa retasan yang tergeletak di sekitar dan saya pikir itu membuat ini agak independen dari perpustakaan mana pun).Format file input adalah PPM
sumber
Java - garis acak
Solusi yang sangat mendasar yang menarik garis acak dan menghitung bagi mereka warna gambar sumber rata-rata. Warna latar diatur ke warna rata-rata sumber.
L = 5000, m = 10, M = 50
L = 10000, m = 10, M = 50
EDIT
Saya telah menambahkan algoritma genetika yang menangani populasi garis. Pada setiap generasi, kami hanya menyimpan 50% baris terbaik, menjatuhkan yang lain dan menghasilkan yang baru secara acak. Kriteria untuk menjaga garis adalah:
Sangat mengecewakan saya, algoritme tampaknya tidak benar-benar meningkatkan kualitas gambar :-( hanya garis yang semakin paralel.
Generasi pertama (5000 baris)
Generasi kesepuluh (5000 baris)
Bermain dengan parameter
sumber
C - garis lurus
Pendekatan dasar dalam C yang beroperasi pada file ppm. Algoritme mencoba menempatkan garis vertikal dengan panjang garis optimal untuk mengisi semua piksel. Warna latar belakang dan warna garis dihitung sebagai nilai rata-rata dari gambar asli (median setiap saluran warna):
L = 5000, m = 10, M = 50
L = 5000, m = 10, M = 50
L = 100000, m = 10, M = 50
sumber
Python 3 berbasis dari "garis agak acak dan kemudian beberapa", ditambah deteksi tepi sobel.
kode secara teoritis dapat berjalan selamanya (jadi saya bisa menjalankannya semalaman untuk bersenang-senang), tetapi mencatat kemajuannya, sehingga semua gambar diambil dari tanda 1-10 menit.
Pertama kali membaca gambar, dan kemudian menggunakan deteksi tepi sobel untuk menemukan sudut semua tepi, untuk memastikan bahwa garis tidak masuk pada warna lain. Setelah satu baris dari panjang acak dalam (lengthmin, lengthmax) diatur, itu kemudian menguji untuk melihat apakah itu berkontribusi pada keseluruhan gambar. Sementara garis yang lebih kecil lebih baik, saya mengatur panjang garis dari 10-50.
sumber