Videolarınıza zekice bir matematik uygulamak ve titremeyi azaltmak için bu tekniği kullanın.

Video sabitleme, video çekimlerinde istenmeyen hareket ve titremeyi azaltan bir tekniktir. Elde çekim, titreşim ve hareket, sabit olmayan kamera hareketlerine neden olabilir. Video sabitleme, daha pürüzsüz görünen bir video üretir.

Video sabitlemenin birincil amacı, kameranın ardışık kareler arasındaki hareketini tahmin etmektir. İşlem daha sonra çerçeveleri hizalamak için uygun dönüşümleri uygulayabilir. Bu, algılanan hareketi en aza indirir.

Ortamınızı Kurma

La başlamak sanal ortam oluşturma programı çalıştırmak için kurduğunuz paketlerin mevcut paketlerle çakışmamasını sağlamak için. Ardından, gerekli kitaplıkları yüklemek için bu terminal komutunu çalıştırın:

pip kurulumu opencv-python numpy

Bu komut, NumPy ve OpenCV kitaplıklarını yükler. NumPy, sayısal görevler için araçlar sağlar OpenCV ise bilgisayarla görme görevleriyle ilgilenir.

Tam kaynak kodu bir GitHub deposu.

Gerekli Kitaplıkları İçe Aktarma ve Üç Önemli İşlevi Tanımlama

instagram viewer

Yeni bir Python dosyası oluşturun ve ona istediğiniz bir ad verin. Komut dosyasının başında NumPy ve OpenCV kitaplıklarını içe aktarın.

içe aktarmak dizi gibi np
içe aktarmak CV2

Bu kitaplıkları içe aktarmak, işlevlerini kodunuzda kullanmanızı sağlayacaktır.

Ardından, stabilizasyon süreci için çok önemli olacak üç işlevi tanımlayın.

hesap_hareket_ortalama İşlevi

Bir işlev oluşturun ve adlandırın hesapla_hareketli_ortalama. Bu işlev, belirttiğiniz yarıçapı kullanarak belirli bir eğrinin hareketli ortalamasını hesaplar. Belirli bir pencere boyutuna ve tek tip bir çekirdeğe sahip bir evrişim işlemi kullanır. Bu hareketli ortalama, yörüngedeki dalgalanmaları yumuşatmaya yardımcı olur.

kesinliklehesapla_hareketli_ortalama(eğri, yarıçap):
# Belirli bir yarıçapı kullanarak bir eğrinin hareketli ortalamasını hesaplayın
pencere_boyutu = 2 * yarıçap + 1
çekirdek = np.ones (window_size) / window_size
eğri_padded = np.lib.pad (eğri, (yarıçap, yarıçap), 'kenar')
smoothed_curve = np.convolve (curve_padded, çekirdek, mod='Aynı')
smoothed_curve = smoothed_curve[yarıçap:-yarıçap]
geri dönmek düzleştirilmiş_eğri

İşlev düzgün bir eğri döndürür. Eğrideki gürültüyü ve dalgalanmaları azaltmaya yardımcı olur. Bunu, kayan pencere içindeki değerlerin ortalamasını alarak yapar.

smooth_trajectory İşlevi

Başka bir işlev oluşturun ve adlandırın pürüzsüz_yörünge. Bu işlev, yörüngenin her boyutunda hareketli ortalamayı uygulayacaktır. Bunu, orijinal yörüngenin düzleştirilmiş bir kopyasını oluşturarak başaracaktır. Bu, videonun kararlılığını daha da artıracaktır.

kesinliklepürüzsüz_yörünge(Yörünge):
# Her boyutta hareketli ortalamayı kullanarak yörüngeyi düzleştirin
smoothed_trajectory = np.copy (yörünge)

için Ben içinde menzil(3):
smoothed_trajectory[:, i] = hesapla_hareketli_ortalama(
yörünge[:, i],
yarıçap=SMOOTHING_RADIUS
)

geri dönmek smoothed_trajectory

bu pürüzsüz_yörünge işlevi düzleştirilmiş bir yörünge döndürür.

fix_border İşlevi

Son bir işlev oluşturun ve adlandırın düzeltme_border. Bu işlev, bir döndürme ve ölçekleme dönüşümü uygulayarak çerçevenin kenarlığını sabitleyecektir. Girdi çerçevesini alır, şeklini hesaplar, bir dönüşüm matrisi oluşturur ve dönüşümü çerçeveye uygular. Son olarak, sabit çerçeveyi döndürür.

kesinlikledüzeltme_border(çerçeve):
# Döndürme ve ölçeklendirme dönüşümü uygulayarak çerçeve kenarlığını düzeltin
çerçeve_şekli = çerçeve.şekil

matris = cv2.getRotationMatrix2D(
(çerçeve_şekli[1] / 2, çerçeve_şekli[0] / 2),
0,
1.04
)

çerçeve = cv2.warpAffine (çerçeve, matris, (çerçeve_şekil[1], çerçeve_şekli[0]))
geri dönmek çerçeve

bu düzeltme_border işlevi, dengelenmiş çerçevelerde, sabitleme işleminin neden olduğu herhangi bir sınır yapaylığının olmamasını sağlar.

Video Sabitlemeyi Başlatma ve Girişi Alma

Yörünge yumuşatma işlevinin kullanacağı yarıçapı ayarlayarak başlayın.

DÜZGÜNLEŞTİRME_RADIUS = 50

Ardından, sabitlemek istediğiniz titreyen videonun video yolunu girin.

# Giriş video dosyasını açın
# Web kameranızı kullanmak için yolu 0 ile değiştirin
büyük harf = cv2.VideoCapture("inputvid.mp4")

Titreyen videonun özelliklerini alın:

çerçeve sayısı = int (cap.get (cv2.CAP_PROP_FRAME_COUNT))
genişlik = int (cap.get (cv2.CAP_PROP_FRAME_WIDTH))
yükseklik = int (cap.get (cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get (cv2.CAP_PROP_FPS)

Çıktı biçimini ayarlayın. Bu, programın stabilize edilmiş videoyu kaydedeceği formattır. herhangi birini kullanabilirsiniz ortak video formatı beğendin

fourcc = cv2.VideoWriter_fourcc(*"mp4v")

Son olarak, video yazıcısını başlatın:

çıkış = cv2.VideoWriter("video_out.mp4", dörtcc, fps, (2 * en boy))

Video yazıcısına ilettiğiniz dosya adının uzantısı, çıktı biçiminde ayarladığınız adla aynı olmalıdır.

Çerçeveleri Okuma ve İşleme

Titreyen videoyu işlemenin ilk adımı burada başlar. Giriş videosundan kareleri okumayı, dönüşümleri hesaplamayı ve dönüşümler dizisini doldurmayı içerir.

İlk kareyi okuyarak başlayın.

_, önceki_çerçeve = cap.read()
önceki_gray = cv2.cvtColor (prev_frame, cv2.COLOR_BGR2GRAY)

Ardından dönüşüm dizisini başlatın. Her çerçeve için bilgi depolayacaktır.

dönüşümler = np.zeros((num_frames - 1, 3), np.float32)

Son olarak, ardışık çerçeveler arasındaki optik akışı hesaplamanız gerekir. Ardından, noktalar arasındaki afin dönüşümü tahmin edin.

için Ben içinde aralık (kare sayısı - 2):
# Ardışık çerçeveler arasındaki optik akışı hesaplayın
prev_points = cv2.goodFeaturesToTrack(
önceki_gri,
maksimumKöşeler=200,
kaliteSeviyesi=0.01,
minMesafe=30,
blokBoyutu=3
)

başarı, curr_frame = cap.read()

eğerOlumsuz başarı:
kırmak

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

curr_points, durum, hata = cv2.calcOpticalFlowPyrLK(
önceki_gri,
curr_gray,
önceki_noktalar,
Hiçbiri
)

ileri sürmek önceki_points.shape == curr_points.shape
idx = np.where (durum == 1)[0]
önceki_noktalar = önceki_noktalar[idx]
curr_points = curr_points[idx]

# Noktalar arasındaki afin dönüşümü tahmin edin
matris, _ = cv2.estimateAffine2D(prev_points, curr_points)
çeviri_x = matris[0, 2]
çeviri_y = matris[1, 2]
döndürme_açı = np.arctan2(matris[1, 0], matris[0, 0])
dönüşümler[i] = [çeviri_x, çeviri_y, döndürme_açı]
önceki_gray = curr_gray

Döngü, dönüşümleri hesaplamak için her kareyi (son kare hariç) yineler. Lucas-Kanade yöntemini kullanarak ardışık çerçeveler arasındaki optik akışı hesaplar. cv2.goodFeaturesToTrack önceki karedeki özellik noktalarını algılar önceki_gray. Daha sonra, cv2.calcOpticalFlowPyrLK geçerli çerçevede bu noktaları izler curr_gray.

Yalnızca durumu 1 olan noktalar (başarılı izlemeyi gösterir), bir afin dönüşüm matrisinin tahmin edilmesine yardımcı olur. Kod şu bilgileri günceller: önceki_gray sonraki yineleme için geçerli gri tonlama çerçevesiyle değişken.

Yörüngeyi Düzleştirme

İstikrarlı bir sonuç elde etmek için dönüşümlerden elde edilen yörüngeyi yumuşatmanız gerekir.

# Dönüşümleri kümülatif olarak toplayarak yörüngeyi hesaplayın
yörünge = np.cumsum (dönüşümler, eksen=0)

# Hareketli ortalamayı kullanarak yörüngeyi düzleştirin
smoothed_trajectory = smooth_trajectory (yörünge)

# Düzleştirilmiş ve orijinal yörünge arasındaki farkı hesaplayın
fark = smoothed_trajectory - yörünge

# Pürüzsüz elde etmek için farkı orijinal dönüşümlere geri ekleyin
# dönüşümler
transforms_smooth = dönüşümler + fark

Yukarıdaki kod, kamera hareketinin yörüngesini hesaplar ve yumuşatır.

Çerçeveleri Sabitleme ve Yazma

Son adım, kareleri stabilize etmek ve stabilize edilmiş videoyu bir çıktı dosyasına yazmaktır.

Video yakalamayı sıfırlayarak başlayın. Bu, gelecekteki işlemlerin videonun başından itibaren okunmasını sağlar.

cap.set (cv2.CAP_PROP_POS_FRAMES, 0)

Ardından, her kareyi işleyerek videoyu sabitleyin.

# Her kareyi işleyin ve videoyu sabitleyin
için Ben içinde aralık (kare sayısı - 2):
başarı, çerçeve = cap.read()

eğerOlumsuz başarı:
kırmak

çeviri_x = transforms_smooth[i, 0]
çeviri_y = transforms_smooth[i, 1]
rotasyon_açı = transforms_smooth[i, 2]

# Stabilizasyon için dönüşüm matrisini oluşturun
transformasyon_matrisi = np.sıfırlar((2, 3), np.float32)
transformasyon_matrisi[0, 0] = np.cos (rotation_angle)
transformasyon_matrisi[0, 1] = -np.sin (rotation_angle)
transformasyon_matrisi[1, 0] = np.sin (rotation_angle)
transformasyon_matrisi[1, 1] = np.cos (rotation_angle)
transformasyon_matrisi[0, 2] = çeviri_x
transformasyon_matrisi[1, 2] = çeviri_y

# Çerçeveyi sabitlemek için dönüşümü uygulayın
frame_stabilized = cv2.warpAffine(
çerçeve,
dönüşüm_matrisi,
(en boy)
)

# Stabilize edilmiş çerçevenin kenarlığını düzeltin
frame_stabilized = fix_border (frame_stabilized)

# Orijinal ve sabitlenmiş çerçeveleri yan yana birleştirin
frame_out = cv2.hconcat([çerçeve, çerçeve_stabilize])

# Genişliği 1920 pikseli aşarsa çerçeveyi yeniden boyutlandırın
eğer frame_out.shape[1] > 1920:
frame_out = cv2.resize(
çerçeve_out,
(frame_out.shape[1] // 2, frame_out.shape[0] // 2)
)

# Öncesi ve sonrası kareleri göster
cv2.imshow("Önce ve sonra", çerçeve_out)
cv2.waitKey(10)

# Çerçeveyi çıktı video dosyasına yazın
out.write (çerçeve_çıkışı)

Yukarıdaki kod, çevirme ve döndürme ayarlamaları da dahil olmak üzere hesaplanan dönüşümleri kullanarak her çerçeveyi dengeler. Daha sonra bir karşılaştırma sağlamak için sabitlenmiş çerçeveleri orijinal çerçevelerle birleştirir.

Video Yakalama ve Yazıcıyı Serbest Bırakma

Video yakalama ve yazma nesnelerini serbest bırakarak programı sonlandırın.

# Video yakalama ve yazıcıyı serbest bırakın ve açık pencereleri kapatın
cap.release()
out.release()
cv2.destroyAllWindows()

Bu kod ayrıca tüm açık pencereleri kapatır.

Nihai Program Çıktısı

Programın çıktısı şöyle bir şeye benzeyecek:

İşte stabilize edilmiş videoya bir örnek:

Çıktı, titreyen video ile dengelenmiş video arasındaki karşılaştırmayı gösterir.

OpenCV Yeteneklerini Keşfedin

OpenCV'yi bilgisayar görüşünü içeren birçok alanda uygulayabilirsiniz. Bunun nedeni, çok çeşitli işlevler sunmasıdır. Bilgisayar görüşünü içeren daha fazla proje üzerinde çalışarak yeteneklerini keşfetmelisiniz. Bu sizi yeni kavramlarla tanıştıracak ve araştırmanız için yeni alanlar sağlayacaktır.