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

uint8

1

0-tól 255-ig

int8

1

-128-tól 127-ig

uint16

2

0-tól 65 535-ig

int16

2

-32 768-tól 32 767-ig

float

4

IEEE 754 egyszeres pontosságú

bool

1

True / False

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

uint8

int8

int16

uint8

int16

int16

uint8

uint16

uint16

int8

int16

int16

int8

uint16

uint16

uint16

int16

float

bármely

float

float

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.