6.4. Dtype-ok¶
Egy ndarray elemtípusa a dtype-ja. A dtype három dolgot dönt el egyszerre: hány bájtot foglal el az egyes elemek, hogyan értelmezzük a bájtokat, és milyen értéktartományt tud tárolni a tömb. A megfelelő dtype kiválasztása az egyetlen legnagyobb döntés, amely befolyásolja a kamera RAM-használatát.
6.4.1. A támogatott dtype-ok¶
A kamerán a numpy a dtype-ok egy kis halmazát támogatja:
dtype |
bájt |
tartomány |
|---|---|---|
|
1 |
0-tól 255-ig |
|
1 |
-128-tól 127-ig |
|
2 |
0-tól 65 535-ig |
|
2 |
-32 768-tól 32 767-ig |
|
4 |
IEEE 754 egyszeres pontosságú |
|
1 |
|
Nincs int32 vagy int64, és az OpenMV ulab buildje nem engedélyezi az opcionális complex dtype-ot.
Válaszd azt a típust, amely megfelel az adatot előállító hardvernek. Egy 8 bites ADC-minta uint8-at igényel; egy 12 bites ADC-minta elfér egy uint16-ban; egy szürkeárnyalatos kamerából származó luminanciaképpont elfér egy uint8-ban – ezzel a négyszeresét takarítjuk meg annak a RAM-nak, amennyit az alapértelmezett float igényelne.
6.4.2. Az alapértelmezett dtype¶
A Tömbök létrehozása oldalon szereplő minden konstruktor alapértelmezett dtype-ja a float. Érzékelőadatok kezelésekor ez ritkán az, amire az alkalmazásnak szüksége van. Add meg explicit módon a dtype= argumentumot, valahányszor a természetes szélesség kisebb:
sensor = np.array(samples, dtype=np.uint16)
Egy egész értékű tömb újracsomagolása dtype= argumentum nélkül másol és float-tá konvertál, ami egyaránt időbe és RAM-ba kerül. Amikor a teljesítmény számít, nevezd meg a dtype-ot.
6.4.3. Egy meglévő tömb dtype-ja¶
A dtype visszaadja a tömb dtype-ját annak az egész típuskódnak a formájában, amelyet a tömb belsőleg hordoz:
a = np.array([1, 2, 3], dtype=np.uint8)
print(a.dtype) # 66 (the integer value of ``'B'``)
A típuskód egész értékei megegyeznek a numpy modulon közzétett konstansokkal – numpy.uint8, numpy.int8, numpy.uint16, numpy.int16, numpy.float, numpy.bool –, így a dtype és a modulkonstans összehasonlítása az, ahogyan egy szkript elágazik annak függvényében, hogy mit tárol egy tömb:
if a.dtype == np.uint8:
... # uint8 branch
6.4.4. Felfelé konvertálás szabályai¶
Két különböző dtype-ú tömb lehet ugyanazon operátor operandusa. A numpy egy rövid táblázat szerint választja ki az eredménytípust:
bal |
jobb |
eredmény |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bármely |
|
|
A uint16 / int16 sor egyenesen float-ra léptet elő, mert a kamerán a numpy nem rendelkezik 32 bites egész dtype-pal.
Amikor egy bináris operátor egyik oldalán egy Python skalár áll, a skalár a legkisebb megfelelő dtype egyetlen elemű tömbjévé alakul: a 123 uint8 tömbbé válik, a -1000 int16-tá, egy Python float pedig float-tá.
6.4.5. Egész szám túlcsordulása körbefordul¶
Az azonos egész dtype-ú két tömbön végzett műveletek megtartják azt a dtype-ot, még akkor is, ha az eredmény túlcsordul. Az átvitel csendben eldobódik:
a = np.array([200, 200], dtype=np.uint8)
b = np.array([100, 100], dtype=np.uint8)
print(a + b)
Kimenet:
array([44, 44], dtype=uint8)
Az eredmény 300 mod 256 == 44. Amikor egy köztes értéknek nagyobb tartományra van szüksége, mint amennyit a bemeneti dtype enged, először konvertálj:
c = np.array(a, dtype=np.uint16) + b
# array([300, 300], dtype=uint16)
Ez a szabály minden egész operátorra vonatkozik – +, -, *, //, %, &, |, ^. A float tömbök soha nem csordulnak túl (helyette végtelenné lépnek elő), így a konvertálási trükkre csak egész szám esetén van szükség.