6.18. Citra dan ndarray¶
Kelas Image adalah permukaan cepat untuk pekerjaan piksel native kamera: setiap metode di dalamnya beroperasi langsung pada buffer bingkai dalam format piksel native kamera. numpy adalah permukaan numerik generik untuk segala hal lainnya. Dua metode menjembatani keduanya:
image.Image.to_ndarray()-- menyalin piksel sebuah citra ke dalamndarray.Konstruktor
image.Image-- membangun citra baru darindarray.
Bersama-sama, keduanya memungkinkan aplikasi mengambil bingkai, menyerahkannya ke numpy untuk transformasi kustom, lalu menempatkan hasilnya kembali ke dalam citra untuk ditampilkan, disimpan, atau diumpankan kembali ke library citra lainnya.
6.18.1. Citra ke ndarray¶
to_ndarray() mengalokasikan ndarray baru dan menyalin data piksel citra ke dalamnya (dengan pemetaan dtype di bawah). Ini tidak pernah merupakan tampilan langsung ke buffer bingkai citra -- array numpy selalu memiliki byte-nya sendiri. Tanda tangan fungsinya adalah to_ndarray(dtype, *, buffer=None), dan bentuk output bergantung pada format citra:
GRAYSCALE -- array 2-D, bentuk
(height, width).RGB565 -- array 3-D, bentuk
(height, width, 3), bidang dalam urutan R/G/B.
Argumen dtype mengontrol bagaimana setiap nilai piksel 8-bit v dipetakan:
|
elemen |
pemetaan untuk nilai piksel 8-bit |
|---|---|---|
|
|
|
|
|
|
|
|
|
Contoh -- lihat bingkai skala abu-abu sebagai matriks uint8
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))
Kata kunci buffer= memungkinkan aplikasi menggunakan kembali bytearray yang sudah dialokasikan, sehingga kamera tidak harus mengalokasikan yang baru setiap bingkai:
buf = bytearray(320 * 240)
while True:
img = csi0.snapshot()
a = img.to_ndarray('B', buffer=buf)
# ... process a ...
6.18.2. ndarray ke citra¶
Untuk arah sebaliknya, teruskan ndarray sebagai argumen pertama ke image.Image. Konstruktor mengalokasikan buffer citra baru dan menyalin nilai array ke dalamnya, dipotong dan dibulatkan ke 0..255
image.Image(arr, *, buffer=None, copy_to_fb=False)
Konstruktor menyimpulkan geometri dan format piksel dari bentuk array:
bentuk
(h, w)-- citraGRAYSCALE.bentuk
(h, w, 3)-- citraRGB565.
ndarray harus memiliki dtype float; konstruktor hanya mendukung kasus tersebut saat ini. Nilai dibulatkan dan dipotong ke rentang 0..255.
buffer= memungkinkan aplikasi menyediakan bytearray yang sudah dialokasikan untuk citra yang dihasilkan. copy_to_fb=True menulis hasil ke buffer bingkai kamera, yang merupakan pilihan tepat ketika hasilnya harus muncul di pratinjau IDE.
6.18.3. Perjalanan pulang-pergi¶
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. Kapan harus menjembatani¶
Jembatan ini adalah jawaban yang tepat ketika aplikasi membutuhkan operasi numerik generik yang tidak disediakan oleh metode image bawaan -- filter kustom, pencampuran kustom, non-linearitas yang tidak biasa -- atau ketika data piksel harus digabungkan dengan data non-citra (sumbu IMU, sampel audio) dalam satu komputasi.
Ini bukan jawaban yang tepat untuk pemrosesan piksel throughput tinggi yang sudah ditangani oleh kelas Image. Metode bawaan beroperasi langsung pada buffer bingkai dalam format piksel native kamera dan jauh lebih cepat daripada ekspresi numpy yang setara. Gunakan jembatan untuk operasi yang belum disediakan oleh library citra.