Tutorial ini akan menunjukkan kepada Anda cara membuat animasi GIF menggunakan OpenCV, Python dan ImageMagick. Kemudian gabungkan metode ini untuk membuat generator meme dengan OpenCV!
Kita semua harus tertawa dari waktu ke waktu. Dan mungkin cara terbaik untuk menemukan lulza adalah dengan meme. Beberapa favorit saya:
- Kermit the Frog: "Tapi Ini Bukan urusanku"
- Kucing pemarah
- Gagal Epik
- Good guy greg
Tetapi bagi saya pribadi, tidak ada meme ini yang dapat dibandingkan dengan meme "Deal With It" ("Deal with it" atau "Understand it it"), sebuah contoh yang diberikan pada awal artikel.Biasanya digunakan dalam kasus berikut:
- Sebagai jawaban atau keberatan kepada seseorang yang tidak menyetujui sesuatu yang telah Anda lakukan / katakan ("Atasi")
- Kenakan kacamata Anda seolah-olah Anda pergi dan meninggalkan orang itu sendirian dengan masalahnya (βPahami itu sendiriβ)
Beberapa tahun yang lalu saya membaca artikel yang menyenangkan di blog penulis, yang saya tidak ingat bagaimana menghasilkan meme seperti itu menggunakan visi komputer. Minggu lalu saya tidak dapat menemukan panduan ini di mana pun, jadi sebagai seorang blogger, seorang ahli penglihatan komputer dan ahli meme, saya memutuskan untuk menulis tutorial sendiri! (Omong-omong, jika Anda tidak sengaja mengetahui sumber aslinya, beri tahu saya agar saya dapat berterima kasih kepada penulis.
UPD: Baru saja menemukan artikel asli dari blog Kirk Kaiser,
MakeArtWithPython ).
Mengembangkan generator meme di OpenCV akan mengajarkan kita sejumlah keterampilan praktis yang berharga, termasuk:
- Deteksi Wajah Menggunakan Teknik Pembelajaran Jauh
- Menggunakan perpustakaan dlib untuk mendeteksi landmark wajah dan mengekstrak area mata
- Cara menghitung sudut rotasi antara mata berdasarkan informasi yang diterima
- Dan akhirnya, cara membuat GIF animasi menggunakan OpenCV (dengan sedikit bantuan dari ImageMagick)
Panduan ini harus menyenangkan dan menghibur - dan pada saat yang sama mengajarkan Anda keterampilan pemrograman visi komputer yang berguna di dunia nyata.
Membuat GIF dengan OpenCV
Pada bagian pertama panduan ini, kami akan membahas kondisi dan dependensi yang diperlukan untuk proyek ini, termasuk konfigurasi lingkungan pengembangan yang tepat.
Kemudian pertimbangkan struktur proyek / katalog untuk generator GIF OpenCV kami.
Segera setelah kami memahami struktur proyek, kami akan mempertimbangkan: 1) file konfigurasi kami; 2) skrip Python yang bertanggung jawab untuk membuat GIF dengan OpenCV.
Akhirnya, kami akan mengevaluasi hasil program pada meme populer "Deal With It".
Prasyarat dan Ketergantungan
Fig. 1. Kami akan menggunakan OpenCV, dlib dan ImageMagick untuk membuat GIFOpencv dan dlib
OpenCV diperlukan untuk menentukan wajah dalam bingkai dan pemrosesan gambar dasar. Ikuti salah satu
panduan instalasi OpenCV saya
jika OpenCV tidak diinstal pada sistem.
Kami menggunakan Dlib untuk mendeteksi landmark wajah, yang memungkinkan kami menemukan dua mata di wajah dan mengenakan kacamata hitam. Anda dapat
menginstal dlib menggunakan instruksi ini .
Imagemagick
Jika Anda tidak terbiasa dengan
ImageMagick , maka sia-sia. Ini adalah alat baris perintah lintas platform dengan banyak fitur pemrosesan gambar.
Apakah Anda ingin mengonversi PNG / JPG ke PDF dengan satu perintah? Tidak masalah
Ada beberapa gambar dari mana Anda perlu membuat PDF multi-halaman? Dengan mudah.
Perlu menggambar poligon, garis, dan bentuk lainnya? Dan itu mungkin.
Bagaimana dengan gradasi warna bets atau mengubah ukuran semua gambar dengan satu perintah? Untuk melakukan ini, Anda tidak perlu menulis beberapa baris dengan Python untuk OpenCV.
ImageMagick juga menghasilkan GIF dari gambar apa pun.
Untuk menginstal ImageMagick di Ubuntu (atau Raspbian) cukup gunakan apt:
Membuat GIF dengan OpenCVShell
$ sudo apt-get install imagemagick
Di macOS, Anda dapat menggunakan HomeBrew:
$ brew install imagemagick
iblis
Di sebagian besar artikel, kursus, dan buku, saya menggunakan
paket pemrosesan gambar
imutils saya yang nyaman. Itu diinstal pada sistem atau lingkungan virtual menggunakan pip:
$ pip install imutils
Struktur proyek
Fig. 2. Struktur proyek mencakup dua direktori, file konfigurasi dan skrip PythonAda dua katalog dalam proyek kami:
images/
: contoh gambar input yang ingin kita buat GIF animasi. Saya menemukan beberapa gambar dengan saya, tetapi jangan ragu untuk menambahkan gambar Anda sendiri.assets/
: folder ini berisi detektor wajah, detektor tengara wajah, dan semua gambar + topeng terkait kami. Dengan aset ini, kami akan meletakkan poin dan teks pada gambar asli dari folder pertama.
Karena banyaknya parameter yang dapat dikonfigurasi, saya memutuskan untuk membuat file konfigurasi JSON, yang: 1) akan memudahkan pengeditan parameter; 2) akan membutuhkan lebih sedikit argumen baris perintah. Semua parameter konfigurasi yang diperlukan untuk proyek ini terdapat di
config.json
.
Pertimbangkan konten
config.json
dan
create_gif.py
.
Catatan Per.: Kode proyek dan manual 17 halaman tentang visi komputer, pembelajaran mesin, dan OpenCV dikeluarkan setelah pendaftaran (mirror: kode sumber , manual ).Generasi GIF dengan OpenCV
Jadi, mari kita lanjutkan dan mulai membuat generator GIF OpenCV kami!
Konten file konfigurasi JSON
Mari kita mulai dengan file konfigurasi JSON, dan kemudian beralih ke skrip Python.
Buka file
config.json
baru dan masukkan pasangan kunci / nilai berikut:
Membuat GIF dengan OpenCVPython
{ "face_detector_prototxt": "assets/deploy.prototxt", "face_detector_weights": "assets/res10_300x300_ssd_iter_140000.caffemodel", "landmark_predictor": "assets/shape_predictor_68_face_landmarks.dat",
Ini adalah file model
pendeteksi wajah OpenCV dalam pembelajaran mendalam .
Baris terakhir adalah jalur menuju prediktor wajah dlib.
Dan sekarang kita memiliki beberapa jalur ke file gambar:
"sunglasses": "assets/sunglasses.png", "sunglasses_mask": "assets/sunglasses_mask.png", "deal_with_it": "assets/deal_with_it.png", "deal_with_it_mask": "assets/deal_with_it_mask.png",
Ini adalah jalur menuju kacamata hitam, teks, dan topeng yang cocok untuk mereka, yang ditunjukkan di bawah ini.
Pertama, kacamata hitam dan topeng mewah:
Fig. 3. Anda tidak suka kacamata dengan piksel? Cukup tahan dengan ituFig. 4. Anda tidak mengerti mengapa Anda membutuhkan topeng untuk kacamata hitam? Cukup tahan dengan itu - atau baca sisa artikel untuk jawabannya.Dan sekarang teks kita adalah "DEAL WITH IT" dan topengnya:
Fig. 5. Apakah Anda membenci Helvetica Neue Condensed? MenghadapinyaFig. 6: Topeng ini memungkinkan Anda untuk menggambar batas di sekitar teks. Oh, mungkin Anda tidak mau, apakah Anda ingin perbatasan? Yah, tahan dengan ituMasker diperlukan untuk melapisi gambar yang sesuai pada foto: kita akan membahasnya nanti.
Sekarang atur beberapa parameter untuk generator meme:
"min_confidence": 0.5, "steps": 20, "delay": 5, "final_delay": 250, "loop": 0, "temp_dir": "temp" }
Berikut adalah definisi untuk masing-masing parameter:
min_confidence
: probabilitas deteksi wajah minimum yang diperlukan.steps
: jumlah bingkai dalam animasi akhir. Setiap "langkah" memindahkan kacamata hitam dari batas atas ke bawah ke target (yaitu ke mata).delay
: delay antar frame dalam seperseratus detik.final_delay
: penundaan frame terakhir dalam seperseratus detik (berguna dalam konteks ini, karena kami ingin teks ditampilkan lebih lama daripada frame lainnya).loop
: nilai nol menunjukkan bahwa GIF berulang selamanya, jika tidak tentukan bilangan bulat positif untuk jumlah pengulangan animasi.temp_dir
: direktori sementara di mana masing-masing frame akan disimpan sebelum membuat GIF final.
Meme, GIF, dan OpenCV
Kami membuat file konfigurasi JSON, sekarang mari kita beralih ke kode asli.
Buka file baru,
create_gif.py
nama
create_gif.py
dan rekatkan kode berikut:
Di sini kami mengimpor paket yang diperlukan. Secara khusus, kita akan menggunakan imutils, dlib dan OpenCV. Untuk menginstal dependensi ini, lihat bagian Prasyarat dan Ketergantungan di atas.
Sekarang skrip memiliki paket yang diperlukan, jadi
overlay_image
mendefinisikan fungsi
overlay_image
:
def overlay_image(bg, fg, fgMask, coords):
Fungsi
overlay_image
memaksakan foreground (
fg
) di bagian atas gambar latar belakang (
bg
) pada koordinat
coords
( koordinat
(x, y) ), mewujudkan transparansi alpha di atas foreground mask
fgMask
.
Untuk membiasakan diri dengan dasar-dasar OpenCV, seperti bekerja dengan topeng, pastikan untuk membaca
panduan ini .
Untuk menyelesaikan proses blending, lakukan alpha blending:
def alpha_blend(fg, bg, alpha):
Implementasi alpha blending ini juga tersedia
di blog LearnOpenCV .
Intinya, kami akan mengonversi saluran latar, latar belakang, dan alfa ke angka titik mengambang dalam rentang
[0, 1] . Kemudian kita melakukan alpha blending, tambahkan foreground dan background untuk mendapatkan hasil bahwa kita kembali ke fungsi pemanggilan.
Kami juga akan membuat fungsi pembantu yang memungkinkan menghasilkan GIF dari serangkaian jalur gambar menggunakan ImageMagick dan perintah
convert
:
def create_gif(inputPath, outputPath, delay, finalDelay, loop):
Fungsi
create_gif
mengambil satu set gambar dan mengumpulkannya ke dalam animasi GIF dengan penundaan yang ditentukan antara frame dan loop. ImageMagick memproses semua ini - kita cukup membungkus perintah
convert
dalam fungsi yang secara dinamis memproses berbagai parameter.
Untuk melihat argumen
convert
tersedia,
lihat dokumentasi . Di sana Anda akan melihat berapa banyak fungsi yang dimiliki tim ini!
Khususnya dalam fungsi ini, kami:
- Ambil
imagePaths
. - Pilih jalur gambar terakhir, yang akan memiliki penundaan terpisah.
imagePaths
ulang imagePaths
untuk mengecualikan jalur terakhir.- Kami merakit perintah dengan argumen baris perintah, dan kemudian menginstruksikan sistem operasi untuk
convert
untuk membuat animasi GIF.
Tetapkan naskah argumen perintahnya sendiri:
Kami memiliki tiga argumen baris perintah yang diproses saat runtime:
--config
: path ke file konfigurasi JSON. Kami meninjau file konfigurasi di bagian sebelumnya.--image
: jalur ke gambar input tempat animasi dibuat (mis. mendeteksi wajah, menambahkan kacamata hitam, dan kemudian teks).--output
: path ke GIF yang dihasilkan.
Setiap argumen ini diperlukan saat menjalankan skrip pada baris perintah / terminal.
Unduh file konfigurasi, serta kacamata dan topeng yang sesuai:
Di sini kita memuat file konfigurasi (yang mungkin tersedia di masa depan sebagai kamus Python). Kemudian muat kacamata hitam dan topeng.
Jika ada sesuatu yang tersisa dari skrip sebelumnya, hapus direktori sementara, dan buat ulang direktori sementara yang kosong. Folder sementara akan berisi setiap frame individual dari animasi GIF.
Sekarang muat
pendeteksi wajah pembelajaran dalam OpenCV ke dalam memori:
Untuk melakukan ini, hubungi
cv2.dnn.readNetFromCaffe
. Modul
dnn
hanya tersedia di OpenCV 3.3 atau yang lebih baru. Detektor wajah akan mendeteksi keberadaan wajah dalam gambar:
Fig. 7. Operasi Detektor Wajah Menggunakan OpenCV DNNKemudian muat
prediktor tengara wajah dlib . Ini akan memungkinkan Anda untuk melokalisasi struktur individu: mata, alis, hidung, mulut dan garis dagu:
Fig. 8. Landmark yang ditemukan oleh dlib ditumpangkan di wajah sayaKemudian dalam skrip ini kami mengekstrak hanya area mata.
Pindah, mari kita cari wajah:
Dalam blok ini kita melakukan hal berikut:
- Unduh
image
aslinya. - Kami membangun
blob
untuk dikirim ke detektor wajah jaringan saraf. Artikel ini menjelaskan cara kerja blobFromImage
dari OpenCV. - Lakukan prosedur deteksi wajah.
- Kami menemukan orang dengan nilai probabilitas tertinggi dan membandingkannya dengan batas probabilitas minimum yang dapat diterima. Jika kriteria tidak terpenuhi, keluar saja dari skrip. Kalau tidak, lanjutkan.
Sekarang kita akan mengekstrak wajah dan menghitung landmark:
Untuk mengekstrak wajah dan menemukan landmark wajah, kami melakukan hal berikut:
- Kami mengekstrak koordinat kotak pembatas di sekitar wajah.
- Buat objek
rectangle
di dlib dan terapkan lokalisasi wajah. - Kami mengambil masing-masing koordinat (x, y) dari
leftEyePts
dan rightEyePts
.
Diberikan koordinat mata, Anda dapat menghitung di mana dan bagaimana menempatkan kacamata hitam:
Pertama, kita menghitung pusat masing-masing mata, lalu sudut antara centroid. Operasi yang sama dilakukan dengan
penyelarasan wajah secara horizontal
dalam bingkai .
Sekarang Anda dapat memutar dan mengubah ukuran kacamata. Perhatikan bahwa kami menggunakan
fungsi rotate_bound , bukan hanya
rotate
, sehingga OpenCV tidak memangkas bagian yang tidak terlihat setelah konversi affine.
Operasi yang sama yang diterapkan pada kacamata, berlaku pada topeng. Tetapi pertama-tama Anda perlu mengubahnya menjadi nuansa abu-abu dan binarize, karena topeng selalu biner. Lalu kami memutar dan mengubah ukuran topeng dengan cara yang sama seperti yang kami lakukan dengan kacamata.
Catatan: perhatikan bahwa ketika mengubah ukuran topeng, kami menggunakan interpolasi untuk titik tetangga terdekat, karena topeng hanya memiliki dua nilai (0 dan 255). Metode interpolasi lainnya lebih estetika, tetapi tidak cocok untuk masker. Di sini Anda bisa mendapatkan informasi tambahan tentang interpolasi di titik terdekat terdekat.Tiga blok kode yang tersisa membuat bingkai untuk animasi GIF:
Kacamata jatuh dari bagian atas gambar. Pada setiap bingkai, mereka ditampilkan lebih dekat ke wajah hingga menutupi mata mereka. Menggunakan variabel
"steps"
dalam file konfigurasi JSON, kami menghasilkan koordinat y untuk setiap frame. Untuk melakukan ini, kami menggunakan fungsi
linspace
dari NumPy tanpa banyak usaha.
Garis dengan sedikit pergeseran ke kiri dan ke atas mungkin tampak sedikit aneh, tetapi mereka diperlukan untuk memastikan bahwa kacamata menutupi mata secara keseluruhan, dan tidak hanya bergerak ke titik di mana pusat mata berada. Saya menentukan persentase secara empiris untuk menghitung offset di sepanjang setiap sumbu. Baris berikutnya memastikan tidak ada nilai negatif.
Dengan menggunakan fungsi
overlay_image
,
overlay_image
menghasilkan frame
output
akhir.
Sekarang terapkan teks "DEAL WITH IT" menggunakan mask lain:
Pada langkah terakhir kita memaksakan teks, yang pada kenyataannya adalah gambar lain.
Saya memutuskan untuk menggunakan gambar karena kemampuan rendering font OpenCV sangat terbatas. Selain itu, saya ingin menambahkan bayangan dan perbatasan di sekitar teks, yang lagi-lagi OpenCV tidak bisa.
Di sisa kode ini, kami memuat gambar dan topeng, dan kemudian melakukan alpha blending untuk menghasilkan hasil akhir.
Tetap hanya menyimpan setiap frame ke disk dengan kreasi animasi GIF berikutnya:
Kami menulis hasilnya ke disk. Setelah membuat semua frame, kita memanggil fungsi
create_gif
untuk membuat file animasi GIF. Ingat bahwa ini adalah shell yang meneruskan parameter ke alat baris perintah
convert
ImageMagick.
Akhirnya, hapus direktori keluaran sementara dan file gambar individual.
Hasil
Sekarang bagian yang menyenangkan: mari kita lihat apa yang dihasilkan generator meme kami!
Pastikan untuk
mengunduh kode sumber, gambar contoh, dan model pembelajaran dalam. Kemudian buka terminal dan jalankan perintah berikut:
$ python create_gif.py --config config.json --image images/adrian.jpg \ --output adrian_out.gif [INFO] loading models... [INFO] computing object detections... [INFO] creating GIF... [INFO] cleaning up...
Gambar 9. Animasi GIF yang dihasilkan dengan OpenCV dan ImageMagick dengan skrip Python iniDi sini Anda dapat melihat GIF dibuat menggunakan OpenCV dan ImageMagick. Tindakan berikut dilakukan di atasnya:
- Deteksi wajah saya yang benar.
- Lokalisasi mata dan perhitungan pusat mereka.
- Kacamata jatuh tepat di wajah.
Pembaca blog saya tahu bahwa saya kutu buku besar di Jurassic Park dan sering menyebutkannya di buku, kursus, dan panduan belajar saya.
Tidak suka
Jurassic Park ?
Ok, inilah jawaban saya:
$ python create_gif.py --config config.json --image images/adrian_jp.jpg \ --output adrian_jp_out.gif [INFO] loading models... [INFO] computing object detections... [INFO] creating GIF... [INFO] cleaning up...
Fig. 10. Animasi OpenCV GIF berdasarkan foto dari pemutaran terbaru Jurassic World 2Di sini saya di acara "Jurassic World: 2" dengan T-shirt tematik, dengan segelas cahaya dan buku koleksi.
Cerita menyenangkan:
Lima atau enam tahun yang lalu, saya dan istri saya mengunjungi taman hiburan Epcot Center di Disney World, Florida.
Kami memutuskan untuk melakukan perjalanan untuk menjauh dari musim dingin yang keras di Connecticut, dan sangat membutuhkan sinar matahari.
Sayangnya, di Florida hujan turun terus-menerus, dan suhunya hampir tidak melebihi 10 Β° C.
Di dekat Taman Kanada, Trisha mengambil foto saya: dia berkata bahwa saya terlihat seperti vampir dengan kulit pucat, pakaian gelap dan kerudung, dengan latar belakang taman yang rimbun di belakang:
$ python create_gif.py --config config.json --image images/vampire.jpg \ --output vampire_out.gif [INFO] loading models... [INFO] computing object detections... [INFO] creating GIF... [INFO] cleaning up...
Fig. 11. Menggunakan OpenCV dan Python, Anda dapat membuat meme ini atau GIF animasi lainnyaMalam itu juga, Trisha menerbitkan foto di jejaring sosial - saya harus tahan dengan itu.
Anda yang menghadiri PyImageConf 2018 (
baca ulasannya ) tahu bahwa saya selalu terbuka untuk lelucon. Berikut ini sebuah contoh:
Pertanyaan: Mengapa ayam jago menyeberang jalan? $ python create_gif.py --config config.json --image images/rooster.jpg \ --output rooster_out.gif [INFO] loading models... [INFO] computing object detections... [INFO] creating GIF... [INFO] cleaning up...
Fig. 12. Wajah dikenali bahkan dengan kontras rendah, dan OpenCV memproses foto dengan benar dan menurunkan kacamata hitam.Jawab: Saya tidak akan mengatakan jawabannya - tahan dengan ini.Akhirnya, kami menyimpulkan panduan hari ini dengan meme yang bagus.Sekitar enam tahun yang lalu, ayah saya dan saya mengadopsi seekor beagle kecil, Gemma.Di sini Anda dapat melihat Gemma di bahu saya: $ python create_gif.py --config config.json --image images/pupper.jpg \ --output pupper_out.gif [INFO] loading models... [INFO] computing object detections... [INFO] creating GIF... [INFO] cleaning up...
Fig. 13. Gemma enak. Tidakkah begitu? Lalu "setujui itu!"Tidak setuju bahwa dia lucu? Menghadapinya.Punya Kesalahan AttributeError?
Jangan khawatir!Jika Anda melihat kesalahan ini: $ python create_gif.py --config config.json --image images/adrian.jpg \ --output adrian_out.gif ... Traceback (most recent call last): File "create_gif.py", line 142, in <module> (lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"] AttributeError: module 'imutils.face_utils' has no attribute 'FACIAL_LANDMARKS_IDXS'
... maka Anda hanya perlu memperbarui paket imutils: $ pip install --upgrade imutils Collecting imutils ... Successfully installed imutils-0.5.1
MengapaSecara default, ia imutils.face_utils
menggunakan detektor landmark 68 titik yang dibangun ke dalam dlib (seperti dalam artikel ini). Ada detektor 5-poin yang lebih cepat , yang sekarang juga berfungsi dengan imutils. Saya baru-baru ini memperbarui imutils untuk mendukung kedua detektor (sehingga Anda mungkin melihat kesalahan).Ringkasan
Dalam tutorial hari ini, Anda belajar cara membuat GIF menggunakan OpenCV.Untuk membuat pelajaran menjadi menyenangkan, kami menggunakan OpenCV untuk membuat animasi GIF "Deal With It", sebuah meme populer (dan favorit saya) yang ditemukan dalam satu atau lain bentuk di hampir setiap situs jejaring sosial.Dalam prosesnya, kami menggunakan visi komputer dan pembelajaran mendalam untuk memecahkan beberapa masalah praktis:- Identifikasi orang
- Perkirakan landmark di wajah
- Identifikasi area wajah (dalam hal ini, mata)
- Perhitungan sudut antara mata untuk menyelaraskan wajah
- Buat campuran transparan dengan alpha blending
Akhirnya, kami mengambil satu set gambar yang dihasilkan dan membuat GIF animasi menggunakan OpenCV dan ImageMagick.Saya harap Anda menikmati tutorial hari ini!Jika Anda menyukainya, silakan tinggalkan komentar dan beri tahu saya.Nah, jika Anda tidak menyukainya, itu tidak masalah, cukup tahan. ;)