Buat GIF dengan OpenCV



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:

  1. Sebagai jawaban atau keberatan kepada seseorang yang tidak menyetujui sesuatu yang telah Anda lakukan / katakan ("Atasi")
  2. 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:

  1. Deteksi Wajah Menggunakan Teknik Pembelajaran Jauh
  2. Menggunakan perpustakaan dlib untuk mendeteksi landmark wajah dan mengekstrak area mata
  3. Cara menghitung sudut rotasi antara mata berdasarkan informasi yang diterima
  4. 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 GIF

Opencv 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 Python

Ada 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 itu


Fig. 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? Menghadapinya


Fig. 6: Topeng ini memungkinkan Anda untuk menggambar batas di sekitar teks. Oh, mungkin Anda tidak mau, apakah Anda ingin perbatasan? Yah, tahan dengan itu

Masker 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:

 #    from imutils import face_utils from imutils import paths import numpy as np import argparse import imutils import shutil import json import dlib import cv2 import sys import os 

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): #     (, )  #    (sH, sW) = fg.shape[:2] (x, y) = coords #          #  ,   , **  # ,    overlay = np.zeros(bg.shape, dtype="uint8") overlay[y:y + sH, x:x + sW] = fg # - , **  ** # ,    ,    # ,       alpha = np.zeros(bg.shape[:2], dtype="uint8") alpha[y:y + sH, x:x + sW] = fgMask alpha = np.dstack([alpha] * 3) #  -   , #   - output = alpha_blend(overlay, bg, alpha) #   return output 

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): #  ,    - #        [0, 1] fg = fg.astype("float") bg = bg.astype("float") alpha = alpha.astype("float") / 255 #  - fg = cv2.multiply(alpha, fg) bg = cv2.multiply(1 - alpha, bg) #     ,    output = cv2.add(fg, bg) #   return output.astype("uint8") 

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): #        imagePaths = sorted(list(paths.list_images(inputPath))) #      lastPath = imagePaths[-1] imagePaths = imagePaths[:-1] #   imagemagick 'convert'  #  GIF      #   ( ) cmd = "convert -delay {} {} -delay {} {} -loop {} {}".format( delay, " ".join(imagePaths), finalDelay, lastPath, loop, outputPath) os.system(cmd) 

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:

 #      ap = argparse.ArgumentParser() ap.add_argument("-c", "--config", required=True, help="path to configuration file") ap.add_argument("-i", "--image", required=True, help="path to input image") ap.add_argument("-o", "--output", required=True, help="path to output GIF") args = vars(ap.parse_args()) 

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:

 #    JSON, #     config = json.loads(open(args["config"]).read()) sg = cv2.imread(config["sunglasses"]) sgMask = cv2.imread(config["sunglasses_mask"]) #    (  ),   #  ,  ,     #   GIF- shutil.rmtree(config["temp_dir"], ignore_errors=True) os.makedirs(config["temp_dir"]) 

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:

 # load our OpenCV face detector and dlib facial landmark predictor print("[INFO] loading models...") detector = cv2.dnn.readNetFromCaffe(config["face_detector_prototxt"], config["face_detector_weights"]) predictor = dlib.shape_predictor(config["landmark_predictor"]) 

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 DNN

Kemudian 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 saya

Kemudian dalam skrip ini kami mengekstrak hanya area mata.

Pindah, mari kita cari wajah:

 #       image = cv2.imread(args["image"]) (H, W) = image.shape[:2] blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0)) #        print("[INFO] computing object detections...") detector.setInput(blob) detections = detector.forward() #       ,  #  ,      i = np.argmax(detections[0, 0, :, 2]) confidence = detections[0, 0, i, 2] #    if confidence < config["min_confidence"]: print("[INFO] no reliable faces found") sys.exit(0) 

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:

 #   (x, y)  #    box = detections[0, 0, i, 3:7] * np.array([W, H, W, H]) (startX, startY, endX, endY) = box.astype("int") #    dlib    #       rect = dlib.rectangle(int(startX), int(startY), int(endX), int(endY)) shape = predictor(image, rect) shape = face_utils.shape_to_np(shape) #        ,  #     (lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"] (rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"] leftEyePts = shape[lStart:lEnd] rightEyePts = shape[rStart:rEnd] 

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:

 #       leftEyeCenter = leftEyePts.mean(axis=0).astype("int") rightEyeCenter = rightEyePts.mean(axis=0).astype("int") #      dY = rightEyeCenter[1] - leftEyeCenter[1] dX = rightEyeCenter[0] - leftEyeCenter[0] angle = np.degrees(np.arctan2(dY, dX)) - 180 #      ,  #      sg = imutils.rotate_bound(sg, angle) #     **  ,    #   β€”       # 90%       sgW = int((endX - startX) * 0.9) sg = imutils.resize(sg, width=sgW) #      ( ,   #  ),      #     - β€”   #       , #     sgMask = cv2.cvtColor(sgMask, cv2.COLOR_BGR2GRAY) sgMask = cv2.threshold(sgMask, 0, 255, cv2.THRESH_BINARY)[1] sgMask = imutils.rotate_bound(sgMask, angle) sgMask = imutils.resize(sgMask, width=sgW, inter=cv2.INTER_NEAREST) 

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:

 #    ,   #  N       #    steps = np.linspace(0, rightEyeCenter[1], config["steps"], dtype="int") # start looping over the steps for (i, y) in enumerate(steps): #      #  ,    **    #  ,       #   shiftX = int(sg.shape[1] * 0.25) shiftY = int(sg.shape[0] * 0.35) y = max(0, y - shiftY) # add the sunglasses to the image output = overlay_image(image, sg, sgMask, (rightEyeCenter[0] - shiftX, y)) 

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:

  #    ,    #  "DEAL WITH IT"   if i == len(steps) - 1: #   "DEAL WITH IT"  , #   dwi = cv2.imread(config["deal_with_it"]) dwiMask = cv2.imread(config["deal_with_it_mask"]) dwiMask = cv2.cvtColor(dwiMask, cv2.COLOR_BGR2GRAY) dwiMask = cv2.threshold(dwiMask, 0, 255, cv2.THRESH_BINARY)[1] #       80%   #  oW = int(W * 0.8) dwi = imutils.resize(dwi, width=oW) dwiMask = imutils.resize(dwiMask, width=oW, inter=cv2.INTER_NEAREST) #  ,   ,  #   oX = int(W * 0.1) oY = int(H * 0.8) output = overlay_image(output, dwi, dwiMask, (oX, oY)) 

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:

  #      p = os.path.sep.join([config["temp_dir"], "{}.jpg".format( str(i).zfill(8))]) cv2.imwrite(p, output) #      ,     #   GIF- print("[INFO] creating GIF...") create_gif(config["temp_dir"], args["output"], config["delay"], config["final_delay"], config["loop"]) #  --    print("[INFO] cleaning up...") shutil.rmtree(config["temp_dir"], ignore_errors=True) 

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 ini

Di sini Anda dapat melihat GIF dibuat menggunakan OpenCV dan ImageMagick. Tindakan berikut dilakukan di atasnya:

  1. Deteksi wajah saya yang benar.
  2. Lokalisasi mata dan perhitungan pusat mereka.
  3. 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 2

Di 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 lainnya

Malam 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 

Mengapa

Secara default, ia imutils.face_utilsmenggunakan 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. ;)

Source: https://habr.com/ru/post/id429024/


All Articles