6.18. Képek és ndarray-k

Az Image osztály a kamera-natív képpontfeldolgozás gyors felülete: minden metódusa közvetlenül a képkocka-pufferen dolgozik a kamera natív képpontformátumában. A numpy az általános numerikus felület minden máshoz. Két metódus köti össze a kettőt:

Együtt lehetővé teszik, hogy egy alkalmazás elkapjon egy képkockát, átadja a numpy modulnak egyéni átalakításra, majd az eredményt visszahelyezze egy képbe megjelenítéshez, mentéshez vagy a képkönyvtár többi részébe való visszatápláláshoz.

6.18.1. Kép ndarray-vé

A to_ndarray() egy új ndarray objektumot allokál, és átmásolja bele a kép képpontadatait (az alábbi dtype-leképezéssel). Soha nem nézet a kép képkocka-pufferére – a numpy tömb mindig a saját bájtjait birtokolja. A szignatúra to_ndarray(dtype, *, buffer=None), és a kimeneti alak a képformátumtól függ:

  • GRAYSCALE – 2D tömb, alak: (height, width).

  • RGB565 – 3D tömb, alak: (height, width, 3), a síkok R/G/B sorrendben.

A dtype argumentum szabályozza, hogyan képeződik le minden egyes 8 bites v képpontérték:

dtype

elem

leképezés egy 8 bites v képpontértékhez

'B'

uint8

v (nyers)

'b'

int8

v - 128 (nullára újraközpontosítva)

'f'

float32

float(v) (0.0 … 255.0)

Példa – egy szürkeárnyalatos képkocka megtekintése uint8 mátrixként:

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))

A buffer= kulcsszó lehetővé teszi, hogy az alkalmazás újrahasznosítson egy már allokált bytearray objektumot, így a kamerának nem kell minden képkockához újat allokálnia:

buf = bytearray(320 * 240)
while True:
    img = csi0.snapshot()
    a   = img.to_ndarray('B', buffer=buf)
    # ... process a ...

6.18.2. ndarray képpé

A másik irányba haladva add át a ndarray objektumot az image.Image első argumentumaként. A konstruktor új képpuffert allokál, és átmásolja bele a tömb értékeit, a 0..255 tartományra korlátozva és kerekítve:

image.Image(arr, *, buffer=None, copy_to_fb=False)

A konstruktor a tömb alakjából következteti ki a geometriát és a képpontformátumot:

  • (h, w) alak – GRAYSCALE kép.

  • (h, w, 3) alak – RGB565 kép.

A ndarray dtype-jának float típusúnak kell lennie; a konstruktor jelenleg csak ezt az esetet támogatja. Az értékek a 0..255 tartományra kerekítődnek és korlátozódnak.

A buffer= lehetővé teszi, hogy az alkalmazás megadjon egy már allokált bytearray objektumot az eredménykép számára. A copy_to_fb=True az eredményt a kamera képkocka-pufferébe írja, ami a megfelelő választás, ha az eredménynek meg kell jelennie az IDE előnézetében.

6.18.3. Oda-vissza út

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. Mikor érdemes áthidalni

Ez a híd a helyes válasz, amikor az alkalmazásnak olyan általános numerikus műveletre van szüksége, amelyet a beépített image metódusok nem biztosítanak – egyéni szűrők, egyéni keverések, szokatlan nemlinearitások –, vagy amikor a képpontadatokat nem képi adatokkal (IMU-tengelyek, audiominták) kell egyetlen számításban kombinálni.

Nem ez a helyes válasz a nagy átviteli teljesítményű képpontfeldolgozáshoz, amelyet az Image osztály már lefed. A beépített metódusok közvetlenül a képkocka-pufferen dolgoznak a kamera natív képpontformátumában, és sokkal gyorsabbak, mint az ezzel egyenértékű numpy kifejezés. A hidat azokhoz a műveletekhez vedd elő, amelyeket a képkönyvtár még nem biztosít.