Robotik Yapay Zeka Görüşünün (RAiV) ana tasarım amaçlarından biri derinlik haritasının tahminidir. Bu yazıda, nihayet OpenCV Python kütüphanesini kullanarak sahnenin derinlik haritasını tahmin edeceğiz.

Stereo Görüntüden Derinliğe Giriş

Derinlik haritasının tahmini, zor bir iştir; ve RAiV bu görev için tam olarak hazır haldedir.

RAiV'in stereo kamera çifti senkronize ve kalibre edilmiştir. Derinlik haritasının tahmini için gerekli olan kalibrasyon parametrelerine kullanıcının Python koduyla erişilebilir. Dolayısıyla, yapmanız gerekenler sadece:

  1. Kalibrasyon parametrelerini alın
  2. Stereo görüntü çiftini alın
  3. Derinlik haritasını tahmin edin

Python ile derinlik tahminine hızlıca geçmek isterseniz "Derinlik Haritalama Kolaylaştırıldı" bölümüne atlayabilirsiniz. Sonraki bölümde, RAiV'in tasarım özelliklerine ve derinlik tahmininin ardındaki teoriye daha yakından bakacağız.

Neden 65 mm Taban Çizgisi?

Stereo görüşte, birbirlerinden yatay olarak ayrılmış iki kameramız vardır. Yatay ayrım mesafesine taban çizgisi denir. Bu kameralardan görüntü aldığımızda, aynı sahneyi farklı bakış açılarından elde ederiz. Yakalanan görüntüler aynı sahneyi ve aynı nesneler/özellikleri içerecektir. Ancak, nesnelerin/özniteliklerin yatay piksel koordinatları farklı olacaktır. Aynı nesneler/öznitelikler arasındaki piksel koordinat mesafesine eşitsizlik (disparity) denir. Bir nesne/öznitelik kameraya yakınsa, görüntülerdeki bu mesafe daha büyük olacaktır. Nesne/öznitelik kameradan uzaktaysa, bu mesafe daha küçük olacaktır. Bu derinlik-eşitsizlik ilişkisi aşağıdaki formülle ifade edilir:

$$ Z = \frac{B \times f}{d} $$ $$ Z: Derinlik\:(mm), f: Odak\:Uzunluğu\:(mm), B: Taban\:Çizgisi\:(mm), d: Eşitsizlik\:(mm) $$
Eşitsizlikten Derinlik Formülü.

RAiV'de insan görüşünü örnek almaya karar verdik. Bunu başarmak için, RAiV'in stereo kamera çiftini, insan gözlerinin ortalama taban uzunluğu (yani ortalama gözbebekleri arası mesafe) olan 65 mm'lik bir taban çizgisine sahip olacak şekilde tasarladık.

Yukarıdaki formüle göre, bu taban çizgisinin seçimi doğrudan sonuçlar doğurmaktadır. Bu etkiyi daha net hale getirmek amacıyla, eşitsizliği piksellere dönüştürmek için başka bir formüle ihtiyacımız var:

$$ f_{pixels} = \frac{f_{mm}}{pixelsize} $$ $$ f_{piksel}: Odak\:Uzunluğu\:(piksel), f_{mm}: Odak\:Uzunluğu\:(mm), pixelsize: Bir\:Pikselin\:Fiziksel\:Boyutu\:(mm) $$
Odak Uzunluğu Dönüştürme Formülü.

Yukarıdaki formülleri kullanarak, derinlikten (mm cinsinden) eşitsizliği (piksel cinsinden) hesaplamak için bir formül yazabiliriz:

$$ d_{pixels} = \frac{B \times f_{mm}}{Z \times pixelsize} $$
Derinlikten (mm cinsinden) Eşitsizlik (piksel cinsinden) Formülü.

Varsayılan RAiV parametreleri şunlardır:

Taban Çizgisi (mm) 65 mm
Odak Uzunluğu (mm) 2.8 mm
Piksel Boyutu (mm) 0.0030 mm (3.0 µm)

RAiV şu odak uzaklıklarına sahip lensler sunmaktadır: 2,8 mm, 3,6 mm, 4 mm, 6 mm, 8 mm, 12 mm, 16 mm ve 25 mm. Lütfen sipariş sırasında lens tercihinizi belirtin.

Yukarıdaki tüm bilgilerle aşağıdaki Derinlik (mm) ve Eşitsizlik (piksel) tablosunu oluşturabiliriz:

Derinlik (mm) Eşitsizlik (piksel)
200 303.33
300 202.22
400 151.66
500 121.33
750 80.88
1000 60.64
2000 30.33
3000 20.22
4000 15.16
5000 12.13

RAiV'de kullanılan kameraların çözünürlüğü 1600x1300 pikseldir. Tüm derinlik tahmin örnek kodlarımızda, hız nedenleriyle görüntüleri 800x650 piksel çözünürlüğe ölçeklendiriyoruz. Sonuç olarak, ölçeklendirilmiş çözünürlükle varsayılan RAiV yapılandırması 300 mm ile 3000 mm arasındaki derinlikleri tahmin etmek için uygundur.

Derinlik Haritalama Kolaylaştırıldı

Kodu Hazırlayın ve Yükleyin

RAiV, kutudan çıkar çıkmaz derinlik tahmini yapmaya hazırdır. Aşağıdaki örnek kod:

  • Veri işlem hattı arayüzünü başlatır
  • Stereo derinlik tahmincisini başlatır
  • Sürekli bir döngüde:
    • Veri işlem hattından stereo görüntü çiftini alır
    • Derinlik haritasını tahmin eder
    • Derinlik haritasını bir bilgisayara gönderir

Bu örneği, gerekli tüm modüllerle birlikte Github Depomuzda bulabilirsiniz. Lütfen örnek kodu github deposundan indirin ve web arayüzü üzerinden RAiV'e yükleyin.

import qCU_Net

# For accessing data pipeline
from qCU_Data import qCUData

# For Depth Estimation
from StereoDepthEstimator import StereoDepthEstimator
import depthUtils

# For sending data over TCP
import base64


def main():
    # Create interface
    theQCUData = qCUData()

    # Initialize shared memory
    if not theQCUData.init():
        print("Failed to initialize shared memory")
        return

    # Initialize OpenCV's depth estimation algorithms
    depthScale = 0.5
    depthMinMM = 300
    depthMaxMM = 600
    depthEstimator = StereoDepthEstimator(
        scale_factor=depthScale,
        # The depth values are in milimeters ("mm")
        min_depth=depthMinMM,
        max_depth=depthMaxMM,
    )


    # Enter object detection loop
    try:
        while True:
            # Get Ai data
            ai_data = theQCUData.getDataAi()
            if ai_data:
                if 'error' in ai_data:
                    print(f"Error occurred: {ai_data['error']}")
                else:
                    # NOTE: 1. We are processing AI output images. Stereo camera output can also be processed
                    #       2. Due to the stereo camera setup the output depth map size is 726x585

                    # Process Ai processor output images
                    depthMap = depthUtils.getDepthFromStereo(ai_data, memConfig, depthEstimator)

                    # Get colored depth map
                    coloredDepthMap = depthEstimator.depth_to_colormap(depthMap)
                    coloredDepthMap_b64 = base64.b64encode(coloredDepthMap).decode('utf-8')
                    # Build payload for the transmission
                    payload = {
                        "width": 726,
                        "height": 585,
                        "depth": coloredDepthMap_b64,
                    }
                    qCU_Net.send_data_to_server("192.168.10.2", 12345, payload)
            else:
                # Wait to avoid high CPU utilization
                time.sleep(0.1)
                    
    except Exception as e:
        print(f"An error occurred: {e}")
    finally:
        print("Cleanup completed")


if __name__ == "__main__":
    main()

Canlı Sunum: Veri Hattını Besleyin

Veri hattını tetiklemek için lütfen "Snapshot" düğmesine basın. Görüntü web arayüzünde görüntülenir görüntülenmez, PC tarafı derinlik haritasını alır ve görüntüler.

RAiV ile Derinlik Tahmini

Sırada Ne Var?

3 Boyutlu Nesne Konumlandırmaya Başlamak için:

3B Nesne Algılama: Uç'ta YOLO'ya Derinlik Ekleme

Python SDK'mızı inceleyin:

RAiV Python SDK

Örnek Kodlar İçin Github Depomuzu İnceleyin:

Github Depomuz