6.18. Görüntüler ve ndarray’ler¶
Image sınıfı, kamera için yerel piksel işlemlerinin hızlı yüzeyidir: üzerindeki her metot doğrudan çerçeve arabelleği (frame buffer) üzerinde, kameranın yerel piksel formatında çalışır. numpy ise diğer her şey için kullanılan genel sayısal yüzeydir. İki metot bunları birbirine bağlar:
image.Image.to_ndarray()– bir görüntünün piksellerini birndarrayiçine kopyalar.image.Imageyapıcısı – birndarrayüzerinden yeni bir görüntü oluşturur.
Birlikte kullanıldıklarında, bir uygulamanın bir çerçeve yakalamasına, bunu özel bir dönüşüm için numpy‘a vermesine ve ardından sonucu görüntülemek, kaydetmek veya görüntü kütüphanesinin geri kalanına geri beslemek üzere tekrar bir görüntüye yerleştirmesine olanak tanırlar.
6.18.1. Görüntüden ndarray’e¶
to_ndarray() yeni bir ndarray ayırır ve görüntünün piksel verilerini (aşağıdaki dtype eşlemesiyle) bunun içine kopyalar. Bu hiçbir zaman görüntünün çerçeve arabelleğine (frame buffer) bir görünüm (view) değildir – numpy dizisi her zaman kendi baytlarına sahiptir. İmza to_ndarray(dtype, *, buffer=None) şeklindedir ve çıktının şekli görüntü formatına bağlıdır:
GRAYSCALE – 2 boyutlu dizi,
(height, width)şekli.RGB565 – 3 boyutlu dizi,
(height, width, 3)şekli, düzlemler R/G/B sırasında.
dtype argümanı, her 8 bitlik piksel değeri v‘nin nasıl eşleneceğini kontrol eder:
|
eleman |
8 bitlik bir piksel değeri |
|---|---|---|
|
|
|
|
|
|
|
|
|
Örnek – bir gri tonlamalı çerçeveyi bir uint8 matrisi olarak görüntüleme:
import csi
from ulab import numpy as np
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.GRAYSCALE)
csi0.framesize(csi.QVGA)
img = csi0.snapshot()
a = img.to_ndarray('B') # shape (240, 320), dtype=uint8
print(a.shape, a.dtype)
print("mean brightness:", np.mean(a))
buffer= anahtar sözcüğü, uygulamanın önceden ayırdığı bir bytearray‘i yeniden kullanmasına olanak tanır; böylece kameranın her çerçevede yeni bir tane ayırması gerekmez:
buf = bytearray(320 * 240)
while True:
img = csi0.snapshot()
a = img.to_ndarray('B', buffer=buf)
# ... process a ...
6.18.2. ndarray’den görüntüye¶
Ters yönde gitmek için, ndarray‘i image.Image‘a ilk argüman olarak geçirin. Yapıcı yeni bir görüntü arabelleği ayırır ve dizinin değerlerini 0..255 aralığına sınırlayıp yuvarlayarak bunun içine kopyalar:
image.Image(arr, *, buffer=None, copy_to_fb=False)
Yapıcı, geometriyi ve piksel formatını dizinin şeklinden çıkarır:
şekil
(h, w)–GRAYSCALEgörüntü.şekil
(h, w, 3)–RGB565görüntü.
ndarray‘in dtype’ı float olmalıdır; yapıcı bugün yalnızca bu durumu destekler. Değerler yuvarlanır ve 0..255 aralığına sınırlanır.
buffer=, uygulamanın sonuçtaki görüntü için önceden ayırdığı bir bytearray‘i sağlamasına olanak tanır. copy_to_fb=True sonucu kameranın çerçeve arabelleğine (frame buffer) yazar; bu da sonucun IDE önizlemesinde görünmesi gerektiğinde doğru seçimdir.
6.18.3. Gidiş-dönüş¶
import csi
import image
from ulab import numpy as np
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.GRAYSCALE)
csi0.framesize(csi.QVGA)
img = csi0.snapshot()
a = img.to_ndarray('f') # work in float space
a = 255.0 * (a / 255.0) ** 0.5 # gamma correction
out = image.Image(a, copy_to_fb=True) # back to an image
6.18.4. Köprü ne zaman kullanılır¶
Bu köprü, uygulamanın yerleşik image metotlarının sağlamadığı genel bir sayısal işleme ihtiyaç duyduğunda – özel filtreler, özel harmanlamalar, alışılmadık doğrusal olmayan işlemler – ya da piksel verilerinin görüntü olmayan verilerle (IMU eksenleri, ses örnekleri) tek bir hesaplamada birleştirilmesi gerektiğinde doğru yanıttır.
Bu köprü, Image sınıfının zaten kapsadığı yüksek iş hacimli piksel işleme için doğru yanıt değildir. Yerleşik metotlar doğrudan çerçeve arabelleği (frame buffer) üzerinde, kameranın yerel piksel formatında çalışır ve eşdeğer numpy ifadesinden çok daha hızlıdır. Görüntü kütüphanesinin halihazırda sağlamadığı işlemler için köprüye başvurun.