Derinlik II: Blok Eşleme

Ali Yasin Eser
İyi Programlama
Published in
4 min readDec 29, 2018

--

Selamlar arkadaşlar. Derinlik serisinin ikinci yazısına hoş geldiniz. Bu yazıda blok eşleme(block matching) algoritması hakkında giriş niteliğinde bilgiler edineceğiz. İlk yazımı okuduğunuzu düşünerek açıklamalarda bulunacağım ve daha önceden verdiğim projedeki kodları kullanacağız.

Daha önce sağ ve sol kameralarımızdan aldığımız görüntülerde kalibrasyon ve düzeltme işlemleri yapmıştık. Düzeltme işleminin sonucunda görüntülerdeki objelerin tüm noktaları görüntülerin aynı satırında bulunuyordu. İki görüntüde de olan X noktası için sol görüntünün sütun numarası A, sağ görüntünün sütun numarası B olsun. Basit bir şekilde (A-B) işlemini her noktaya yaparsak ( iki görüntüde de olmayan noktalar durumunda gürültüler oluşacaktır ) elimize disparity görüntüsü geçecektir. Fakat bunu nokta nokta yapmak yerine, eşleme algoritmalarını kullanıyoruz. Bunun sebeplerinden en önemlileri:

  • Nokta bazında eşleme yavaş bir operasyon.
  • Düzeltme/kalibrasyon hatalarından kaynaklanan sebeplerle iki görüntüde de aynı noktalar olmayabiliyor, bazı durumlarda tam olarak satır eşlemesi mümkün olmuyor. Bu durumlarda hata artıyor.

Bu sebepler dolayısıyla blok blok eşlere bakılıyor. Bazı algoritmalar optik akış( optical flow ) mantığını kullanırken, bazıları görüntüyü küçülterek gereken eşleme sayısını azaltıyor. Ben blok eşlemeyi basitçe anlatıyor olacağım, gerisi için referansları ve akademik makaleleri incelemenizi tavsiye ediyorum.

Blok eşleme algoritmalarında sol görüntüden( sol olmak zorunda değil, benim alışkanlığım ) belirlenmiş bir büyüklükten blok alınarak başlanır. Büyük bloklar yumuşak geçişli bir görüntü, çok küçük bloklar da çok gürültülü bir görüntü veriyor. Düzgün seçmekte fayda var. Seçtiğimiz blok sol görüntüden olduğundan dolayı, sağa doğru bir arama gerçekleştiriyoruz. Aramayı tek eksende yapmamız yeterli.

Örnek olarak bir blok seçtiğimizi varsayalım.
Eksen üzerinde arama gerçekleştiriliyor. Buradaki aramada iki yönü ele almış. Optimize bir yaklaşım değil çünkü sağ görüntü mü yoksa sol görüntü mü belli değil.

Blokların eşlenmesi konusuna gelirsek, burada çeşitli formüller mevcut. En çok SAD( Sum of Absolute Differences, Mutlak farkların toplamı) ve SSD( Sum of Squared Differences, Kareler farkının toplamı) kullanılıyor. Çeşitli metotlar var, dilerseniz araştırabilirsiniz. Sonuç değeri ne kadar düşükse bloklar o kadar benziyor demektir. Ve bu bizim disparity değerimiz oluyor.

SAD eşleme metodunun bir örneği.
(Soldan sağa) Sol düzeltilmiş görüntü, sağ düzeltilmiş görüntü, blok eşleme algoritması sonucunda elde edilen disparity haritası.

Blok eşleme konusunda biraz fikir edindiğimize göre kodumuza geçebiliriz. Kod üzerinde blok eşlemenin yanında wls filtresi de kullanıldı. Bunun sebebi filtre ile yumuşatma ve görüntüyü daha iyi yansıtan sonuçlar elde etmemden kaynaklı. Fonksiyonumuz:

Projenin tamamına buradan erişebilirsiniz. Kod basitçe bir eşleyici oluşturuyor. OpenCV bu konularda çok az kaynağa sahip olsa da kod tarafında çok yardımcı. Eşleyicinin parametrelerini inceleyelim:

  • minDisparity: En düşük disparity değeri. Normalde bu değerin sıfır olmasını bekleriz ama düzeltme(rectification) algoritmaları görüntüleri kaydırdığından dolayı gerekebiliyor.
  • numDisparities: Bu değer maksimum-minimum disparity değerine eşittir. Sıfırdan büyük olmalıdır, disparity değerinin aralığıdır.
  • blockSize: Blok penceresinin büyüklüğüdür. [3–11] aralığında olması tavsiye edilir ve tek sayı olmalıdır.
  • P1 ve P2: Görüntünün yumuşatılmasından sorumlu filtrelerdir. P2>P1 olmalıdır.
  • disp12MaxDiff: Disparity hesaplama aşamasında izin verilen maksimum pixel fark aralığıdır.
  • preFilterCap: İşlem öncesi filtrelemede kullanılan bir değerdir. Blok eşleme öncesi görüntünün x-eksende türevi alınarak [-prefiltercap,prefiltercap] aralığı kontrol edilir. Kalan değerler Birchfield-Tomasi maliyet fonksiyonuna tabi tutulur.
  • uniquenessRatio: Hesaplanan değerin maliyet fonksiyonu sonrası ikinci değerle karşılaştırılmasını sağlar( ikinci kontrol mekanizması dersek yanlış olmaz diye düşünüyorum). Normalde değer [5–15] arasıdır.
  • speckleWindowSize: Blok eşlemede aşırı değerlerin silinmesi için kabul edilecek “yumuşak” geçişlerin büyüklüğünü belirler. Sıfır değeri bu işlem sonrası filtreyi iptal eder, kullanılacaksa [50–200] değer aralığı uygundur.
  • speckleRange: Bağlı elemanlar(yumuşak geçiş diye bahsedilen parçalar) arasındaki disparity çeşitliliğini kontrol ederek eliminasyon gerçekleştirir. Eğer bu filtre kullanılacaksa bu parametre 1 veya 2 verilebilir. Değer 16 ile çarpılarak( OpenCV bu değeri çarpıyor ) hesaplanacaktır.

Kod içinde SGBM eşleyicisi kullanılıyor. Sağ ve sol disparity görüntüleri elde edilip birleştiriliyor. WLS filtresi hakkında bilgi edinebilirsem bir yazı daha eklemeyi planlıyorum fakat şu an sadece tüketici konumundayım :)

Proje kodları temel olarak tek ve ikili kamera kalibrasyonu ve derinlik haritası çıkarımını içeriyor. Bu hesaplardan sonra istediğiniz analizi yapabilirsiniz. Ben çalıştığım projede drone kontrolünü gerçekleştiren bir Odroid Board programlıyorum. Hesaplamayı orada gerçekleştirip engelleri kontrol edip ilerlemem gereken yolu belirlemekte kullanabiliyorum. Hayal gücünüzü ve fikirlerinizi ortaya koyarak siz de güzel bir proje başlatabilirsiniz diye umuyorum. Github’da yıldızınızı esirgemeyin :)

Stere Vision konusu giriş seviyesinde bitti diyebilirim. Eğer bir sürpriz yapmayı düşünmezsem farklı konularda sizinle birlikte olabilirim. Saygılar.

--

--

Ali Yasin Eser
İyi Programlama

iOS Developer with Computer Vision and Embedded Systems background. Solo musician with 3 albums.