Gunakan teknik ini untuk menerapkan perhitungan cerdas pada video Anda dan mengurangi goyangan.

Stabilisasi video adalah teknik yang mengurangi gerakan dan guncangan yang tidak diinginkan dalam rekaman video. Pemotretan genggam, getaran, dan gerakan semuanya dapat menyebabkan gerakan kamera tidak stabil. Stabilisasi video menghasilkan video yang tampak lebih halus.

Tujuan utama stabilisasi video adalah memperkirakan gerakan kamera di antara bingkai yang berurutan. Proses kemudian dapat menerapkan transformasi yang sesuai untuk menyelaraskan bingkai. Ini meminimalkan gerakan yang dirasakan.

Menyiapkan Lingkungan Anda

Mulai oleh menciptakan lingkungan virtual untuk memastikan paket yang Anda instal untuk menjalankan program tidak bertentangan dengan yang sudah ada. Kemudian jalankan perintah terminal ini untuk menginstal pustaka yang diperlukan:

pip instal opencv-python numpy

Perintah ini menginstal pustaka NumPy dan OpenCV. NumPy menyediakan alat untuk tugas numerik sementara OpenCV menangani tugas visi komputer.

instagram viewer

Kode sumber lengkap tersedia di a repositori GitHub.

Mengimpor Pustaka yang Diperlukan dan Mendefinisikan Tiga Fungsi Penting

Buat file Python baru dan beri nama sesuai keinginan Anda. Impor pustaka NumPy dan OpenCV di awal skrip.

impor numpy sebagai np
impor cv2

Mengimpor pustaka ini akan memungkinkan Anda untuk menggunakan fungsinya dalam kode Anda.

Selanjutnya, tentukan tiga fungsi yang akan sangat penting untuk proses stabilisasi.

Fungsi count_moving_average

Buat fungsi dan beri nama menghitung_bergerak_rata-rata. Fungsi ini akan menghitung rata-rata bergerak dari kurva yang diberikan menggunakan radius yang Anda tentukan. Ini menggunakan operasi konvolusi dengan ukuran jendela yang ditentukan dan kernel yang seragam. Rata-rata bergerak ini membantu memuluskan fluktuasi dalam lintasan.

defmenghitung_bergerak_rata-rata(kurva, radius):
# Hitung rata-rata pergerakan kurva menggunakan radius tertentu
ukuran_jendela = 2 * radius + 1
kernel = np.ones (ukuran_jendela) / ukuran_jendela
curve_padded = np.lib.pad (kurva, (radius, radius), 'tepian')
smoothed_curve = np.convolve (curve_padded, kernel, mode='sama')
smoothed_curve = smoothed_curve[radius:-radius]
kembali smoothed_curve

Fungsi mengembalikan kurva halus. Ini membantu mengurangi kebisingan dan fluktuasi kurva. Ini dilakukan dengan merata-ratakan nilai di dalam jendela geser.

Fungsi smooth_trajectory

Buat fungsi lain dan beri nama lintasan_halus. Fungsi ini akan menerapkan rata-rata bergerak pada setiap dimensi lintasan. Ini akan mencapai ini dengan membuat salinan lintasan asli yang diperhalus. Ini akan semakin meningkatkan stabilitas video.

deflintasan_halus(lintasan):
# Haluskan lintasan menggunakan rata-rata bergerak pada setiap dimensi
smoothed_trajectory = np.copy (lintasan)

untuk Saya di dalam jangkauan(3):
smoothed_trajectory[:, i] = count_moving_average(
lintasan[:, i],
radius=SMOOTHING_RADIUS
)

kembali smoothed_trajectory

Itu lintasan_halus fungsi mengembalikan lintasan yang diperhalus.

Fungsi fix_border

Buat fungsi terakhir dan beri nama fix_border. Fungsi ini akan memperbaiki batas bingkai dengan menerapkan transformasi rotasi dan penskalaan. Dibutuhkan frame input, menghitung bentuknya, membangun matriks transformasi, dan menerapkan transformasi ke frame. Akhirnya, ia mengembalikan bingkai tetap.

deffix_border(bingkai):
# Perbaiki batas bingkai dengan menerapkan transformasi rotasi dan penskalaan
bingkai_bentuk = bingkai.bentuk

matriks = cv2.getRotationMatrix2D(
(bingkai_bentuk[1] / 2, bingkai_bentuk[0] / 2),
0,
1.04
)

bingkai = cv2.warpAffine (bingkai, matriks, (bentuk_bingkai[1], bingkai_bentuk[0]))
kembali bingkai

Itu fix_border fungsi memastikan bahwa bingkai yang distabilkan tidak memiliki artefak perbatasan yang disebabkan oleh proses stabilisasi.

Menginisialisasi Stabilisasi Video dan Mengambil Masukan

Mulailah dengan mengatur radius yang akan digunakan fungsi perataan lintasan.

SMOOTHING_RADIUS = 50

Kemudian, lewati jalur video dari video goyang yang ingin Anda stabilkan.

# Buka file video masukan
# Ganti jalur dengan 0 untuk menggunakan webcam Anda
tutup = cv2.VideoCapture('inputvid.mp4')

Dapatkan properti video goyah:

num_frames = int (cap.get (cv2.CAP_PROP_FRAME_COUNT))
lebar = int (cap.get (cv2.CAP_PROP_FRAME_WIDTH))
tinggi = int (cap.get (cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get (cv2.CAP_PROP_FPS)

Atur format keluaran. Ini adalah format di mana program akan menyimpan video yang distabilkan. Anda dapat menggunakan apa saja format video umum kamu suka.

empatcc = cv2.VideoWriter_fourcc(*'mp4v')

Terakhir, inisialisasi penulis video:

keluar = cv2.VideoWriter('video_out.mp4', empat cc, fps, (2 * lebar tinggi))

Ekstensi nama file yang Anda berikan ke penulis video harus sama dengan ekstensi yang Anda atur dalam format keluaran.

Membaca dan Memproses Bingkai

Langkah pertama memproses video goyah dimulai di sini. Ini melibatkan membaca frame dari video input, menghitung transformasi, dan mengisi array transformasi.

Mulailah dengan membaca bingkai pertama.

_, prev_frame = cap.read()
prev_gray = cv2.cvtColor (prev_frame, cv2.COLOR_BGR2GRAY)

Kemudian inisialisasi array transformasi. Ini akan menyimpan informasi untuk setiap frame.

transformasi = np.zeros((num_frames - 1, 3), np.float32)

Terakhir, Anda perlu menghitung aliran optik antara bingkai yang berurutan. Kemudian, perkirakan transformasi afin antara titik-titik tersebut.

untuk Saya di dalam rentang (num_frames - 2):
# Hitung aliran optik antara frame berurutan
prev_points = cv2.goodFeaturesToTrack(
prev_gray,
maxCorners=200,
Tingkat kualitas=0.01,
jarak min =30,
ukuran blok=3
)

sukses, curr_frame = cap.read()

jikabukan kesuksesan:
merusak

curr_gray = cv2.cvtColor (curr_frame, cv2.COLOR_BGR2GRAY)

curr_points, status, err = cv2.calcOpticalFlowPyrLK(
prev_gray,
curr_gray,
prev_points,
Tidak ada
)

menegaskan prev_points.shape == curr_points.shape
idx = np.di mana (status == 1)[0]
prev_points = prev_points[idx]
curr_points = curr_points[idx]

# Perkirakan transformasi afin antara titik-titik
matriks, _ = cv2.estimateAffine2D(prev_points, curr_points)
translation_x = matriks[0, 2]
translation_y = matriks[1, 2]
rotasi_angle = np.arctan2(matriks[1, 0], matriks[0, 0])
transformasi[i] = [translation_x, translation_y, rotation_angle]
prev_gray = curr_gray

Perulangan berulang pada setiap frame (kecuali frame terakhir) untuk menghitung transformasi. Ini menghitung aliran optik antara frame berurutan menggunakan metode Lucas-Kanade. cv2.goodFeaturesToTrack mendeteksi titik fitur pada frame sebelumnya prev_gray. Kemudian, cv2.calcOpticalFlowPyrLK melacak titik-titik ini dalam bingkai saat ini curr_gray.

Hanya poin dengan status 1 (menunjukkan pelacakan berhasil) yang membantu memperkirakan matriks transformasi affine. Kode memperbarui prev_gray variabel dengan bingkai skala abu-abu saat ini untuk iterasi berikutnya.

Menghaluskan Lintasan

Anda perlu memuluskan lintasan yang diperoleh dari transformasi untuk mencapai hasil yang stabil.

# Hitung lintasan dengan menjumlahkan transformasi secara kumulatif
lintasan = np.cumsum (transformasi, sumbu=0)

# Ratakan lintasan menggunakan rata-rata bergerak
smoothed_trajectory = smooth_trajectory (lintasan)

# Hitung perbedaan antara lintasan yang dihaluskan dan yang asli
perbedaan = smoothed_trajectory - lintasan

# Tambahkan perbedaan kembali ke transformasi asli untuk mendapatkan kelancaran
# transformasi
transforms_smooth = transformasi + perbedaan

Kode di atas menghitung lintasan gerakan kamera dan menghaluskannya.

Menstabilkan dan Menulis Bingkai

Langkah terakhir adalah menstabilkan bingkai dan menulis video yang distabilkan menjadi file keluaran.

Mulailah dengan mengatur ulang pengambilan video. Ini memastikan operasi selanjutnya akan membaca dari awal video.

cap.set (cv2.CAP_PROP_POS_FRAMES, 0)

Kemudian stabilkan video dengan memproses setiap frame.

# Proses setiap bingkai dan stabilkan video
untuk Saya di dalam rentang (num_frames - 2):
sukses, bingkai = cap.read()

jikabukan kesuksesan:
merusak

translation_x = transforms_smooth[i, 0]
translation_y = transforms_smooth[i, 1]
rotasi_angle = transformasi_smooth[i, 2]

# Buat matriks transformasi untuk stabilisasi
transformasi_matrix = np.nol((2, 3), np.float32)
transformasi_matrix[0, 0] = np.cos (rotasi_angle)
transformasi_matrix[0, 1] = -np.sin (rotasi_angle)
transformasi_matrix[1, 0] = np.sin (rotasi_angle)
transformasi_matrix[1, 1] = np.cos (rotasi_angle)
transformasi_matrix[0, 2] = terjemahan_x
transformasi_matrix[1, 2] = terjemahan_y

# Terapkan transformasi untuk menstabilkan bingkai
frame_stabilized = cv2.warpAffine(
bingkai,
transformasi_matrix,
(lebar tinggi)
)

# Perbaiki batas bingkai yang distabilkan
frame_stabilized = fix_border (frame_stabilized)

# Gabungkan bingkai asli dan yang distabilkan secara berdampingan
frame_out = cv2.hconcat([bingkai, bingkai_stabil])

# Ubah ukuran bingkai jika lebarnya melebihi 1920 piksel
jika frame_out.shape[1] > 1920:
frame_out = cv2.resize(
bingkai_keluar,
(frame_out.shape[1] // 2, frame_out.shape[0] // 2)
)

# Tampilkan bingkai sebelum dan sesudah
cv2.imshow("Sebelum dan sesudah", bingkai_keluar)
cv2.waitKey(10)

# Tulis bingkai ke file video keluaran
keluar.tulis (frame_out)

Kode di atas menstabilkan setiap frame menggunakan transformasi yang dihitung, termasuk penyesuaian translasi dan rotasi. Ini kemudian menggabungkan bingkai yang distabilkan dengan yang asli untuk memberikan perbandingan.

Melepaskan Video Capture dan Writer

Selesaikan program dengan melepaskan tangkapan video dan objek penulis.

# Lepaskan perekam dan penulis video, dan tutup semua jendela yang terbuka
tutup.rilis()
keluar.rilis()
cv2.hancurkanSemuaWindows()

Kode ini juga menutup semua jendela yang terbuka.

Keluaran Program Akhir

Output dari program akan terlihat seperti ini:

Dan inilah contoh video yang distabilkan:

Outputnya menunjukkan perbandingan antara video goyang dan yang stabil.

Jelajahi Kemampuan OpenCV

Anda dapat menerapkan OpenCV di banyak bidang yang melibatkan computer vision. Ini karena ia menawarkan berbagai fungsi. Anda harus mengeksplorasi kemampuannya dengan mengerjakan lebih banyak proyek yang melibatkan visi komputer. Ini akan memperkenalkan Anda pada konsep-konsep baru dan memberi Anda area baru untuk diteliti.