4.14. CSI temelleri¶
csi modülü, Python kodunun kamera sensörünü sürme şeklidir. Bir çerçeve yakalayan her betik aynı üç parçalı yapıyı izler: en üstte içe aktarmalar, ortada tek seferlik yapılandırma ve en altta kameradan çerçeveleri teker teker çeken bir while True döngüsü.
4.14.1. Tipik döngü¶
import csi, image, time
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QVGA)
clock = time.clock()
while True:
clock.tick()
img = csi0.snapshot()
# process img here
print(clock.fps())
4.14.2. Her çağrının yaptığı şey¶
import csi, image, timeÜç modülü içe aktarır.
csisensörü kontrol eder,imagesnapshot()tarafından döndürülenImagesınıfını tanımlar vetime, saniye başına çerçeveyi ölçmek için kullanılantime.clock()yardımcısını sağlar.csi.CSI()Tek bir fiziksel kamera sensörünü saran bir
CSIörneği oluşturur. Yapıcı, kamera çevre birimini talep eder ve sensöre özgü yapılandırmayı kaydeder. Tek sensörlü kameraların birCSIörneği vardır; iki sensörlü kameraların (renkli artı termal, renkli artı olay) ise her biri yapıcıya verilen bircidargümanıyla seçilen iki örneği vardır.csi0.reset()Sensörü besler ve yapılandırır. Varsayılan olarak sensörün sıfırlama pinini darbeler, ardından sensörün I2C yazmaçlarına bilinen bir başlangıç durumu yazar. Sonraki yapılandırma çağrıları –
pixformat,framesize, otomatik kontrol düğmeleri – aynı I2C kontrol veri yolu üzerinden daha fazla yazmaç yazması iter.csi0.pixformat(csi.RGB565)Çıkış piksel biçimini seçen sensör yazmaçlarını yazar. Mevcut seçenekler piksel biçimleri sayfasının tanıttığı biçimlerdir:
RGB565,GRAYSCALE,BAYER,YUV422ve destekleyen sensörlerdeJPEG.csi0.framesize(csi.QVGA)Çıkış çözünürlüğünü seçen yazmaçları yazar.
QVGA320 × 240’tır; adlandırılmış boyutlar, destekleyen sensörlerdeWQXGA2(2592 × 1944, yaklaşık 5 MP) değerine kadar çıkar. Sensörün çıkış yetenekleriyle hizalandığı sürece özel bir(width, height)demeti de çalışır.clock = time.clock()Bir clock yardımcısı oluşturur. Döngü içindeki her
clock.tick()çağrısı yineleme başlangıç zamanını kaydeder;time.clock.fps()son döngü hızını saniye başına çerçeve olarak bildirir.img = csi0.snapshot()Sensörden bir çerçeve yakalar ve onu bir
Imageolarak döndürür. O çerçevenin belleğe nasıl ulaştığının mekaniği daha yakından incelenmeye değerdir.
4.14.3. snapshot belleği nasıl doldurur¶
Sensör, pikselleri sensör veri yolları içinde açıklanan piksel-veri yolunda saniye başına yüzlerce megabayt hızında teslim eder – CPU’nun yazılımda piksel piksel kopyalaması için fazlasıyla hızlı.
Bunun yerine MCU, aktarımı Doğrudan Bellek Erişimi‘ne (DMA) devreder – CPU’dan ayrı, baytları CPU’yu hiç dahil etmeden MCU içinde bir yerden başka bir yere kopyalayan bir donanım motoru. Kamera giriş çevre birimi, gelen her piksel baytını küçük bir yonga üzeri FIFO’ya yakalar; MCU tarafında çalışan ISP aşamaları verileri geçiş sırasında işler; ve DMA motoru tamamlanmış pikselleri RAM’deki bir framebuffer’a karşılık gelen piksel ofsetine yazar. DMA kanalı programlandıktan sonra bu zincirde hiçbir şeyin CPU’ya ihtiyacı yoktur.
snapshot() çağrıldığında:
CSI sürücüsü, DMA motorunu framebuffer’ın adresi, aktarım uzunluğu (bir çerçevelik piksel) ve DMA-tamamlandı kesmesi için bir geri çağırma ile programlar.
Sürücü, kamera giriş çevre birimini etkinleştirir ve sensörün bir sonraki çerçevenin başlangıcını bildirmesini bekler.
Sensör çerçeveyi akıttıkça, çevre birimi her piksel baytını ISP’den ve oradan DMA motoruna geçirir; DMA motoru sonucu RAM’de bir sonraki framebuffer ofsetine yazar. CPU, aktarım sırasında başka kod çalıştırmakta serbesttir.
Çerçevenin son pikseli geldiğinde, DMA tamamlandı kesmesini ateşler, sürücü framebuffer’ı bir
Imageiçine sarar vesnapshot()onu kullanıcı koduna döndürür.
Döndürülen Image, piksel verisinin bir kopyasına sahip değildir – RAM’deki kamera framebuffer’larından birine işaret eder. Kameranın kaç framebuffer tuttuğu ve her snapshot() çağrısında bunların DMA ile kullanıcı kodu arasında nasıl el değiştirdiği, uygulamanın framebuffers() aracılığıyla seçtiği arabelleğe alma moduna bağlıdır.