6.18. Slike i ndarray-evi¶
Klasa Image brza je površina za rad s pikselima u izvornom formatu kamere: svaka njezina metoda izravno operira na međuspremniku slike u izvornom formatu piksela kamere. numpy je generička numerička površina za sve ostalo. Dvije metode ih premošćuju:
image.Image.to_ndarray()– kopira piksele slike undarray.Konstruktor klase
image.Image– gradi novu sliku izndarray.
Zajedno omogućuju aplikaciji da snimi sličicu, preda je modulu numpy za prilagođenu transformaciju, a zatim rezultat vrati natrag u sliku radi prikaza, spremanja ili povratnog prosljeđivanja ostatku biblioteke za rad sa slikama.
6.18.1. Slika u ndarray¶
to_ndarray() alocira novi ndarray i kopira podatke piksela slike u njega (s mapiranjem dtype-a u nastavku). Nikada nije prikaz (view) na međuspremnik slike – numpy polje uvijek posjeduje vlastite bajtove. Potpis je to_ndarray(dtype, *, buffer=None), a izlazni oblik ovisi o formatu slike:
GRAYSCALE – 2-D polje, oblik
(height, width).RGB565 – 3-D polje, oblik
(height, width, 3), ravnine u redoslijedu R/G/B.
Argument dtype upravlja time kako se svaka 8-bitna vrijednost piksela v mapira:
|
element |
mapiranje za 8-bitnu vrijednost piksela |
|---|---|---|
|
|
|
|
|
|
|
|
|
Primjer – prikaz sličice u sivim tonovima kao uint8 matrice:
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))
Ključna riječ buffer= omogućuje aplikaciji da ponovno upotrijebi bytearray koji je već alocirala, pa kamera ne mora alocirati novi za svaku sličicu:
buf = bytearray(320 * 240)
while True:
img = csi0.snapshot()
a = img.to_ndarray('B', buffer=buf)
# ... process a ...
6.18.2. ndarray u sliku¶
U suprotnom smjeru, proslijedite ndarray kao prvi argument klasi image.Image. Konstruktor alocira novi međuspremnik slike i kopira vrijednosti polja u njega, ograničene i zaokružene na 0..255
image.Image(arr, *, buffer=None, copy_to_fb=False)
Konstruktor zaključuje geometriju i format piksela iz oblika polja:
oblik
(h, w)– slikaGRAYSCALE.oblik
(h, w, 3)– slikaRGB565.
ndarray mora imati dtype float; konstruktor danas podržava samo taj slučaj. Vrijednosti se zaokružuju i ograničavaju na raspon 0..255.
buffer= omogućuje aplikaciji da dostavi bytearray koji je već alocirala za rezultantnu sliku. copy_to_fb=True zapisuje rezultat u međuspremnik slike kamere, što je ispravan izbor kada se rezultat treba pojaviti u pretpregledu OpenMV IDE-a.
6.18.3. Povratni put¶
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. Kada premostiti¶
Ovaj most ispravan je odgovor kada aplikaciji treba generička numerička operacija koju ugrađene metode modula image ne pružaju – prilagođeni filtri, prilagođena miješanja, neuobičajene nelinearnosti – ili kada se podaci piksela moraju kombinirati s ne-slikovnim podacima (osi IMU-a, audio uzorci) u jednom izračunu.
Nije ispravan odgovor za obradu piksela visoke propusnosti koju klasa Image već pokriva. Ugrađene metode operiraju izravno na međuspremniku slike u izvornom formatu piksela kamere i znatno su brže od ekvivalentnog numpy izraza. Posegnite za mostom za one operacije koje biblioteka za rad sa slikama već ne pruža.