6.4. Dtype-tyypit

ndarray-taulukon alkioiden tyyppi on sen dtype. Dtype määrää kolme asiaa kerralla: kuinka monta tavua kukin alkio vie, kuinka tavut tulkitaan ja mitä arvoaluetta taulukko voi tallentaa. Oikean dtypen valinta on yksittäinen suurin päätös, joka vaikuttaa kameran RAM-muistin käyttöön.

6.4.1. Tuetut dtype-tyypit

numpy tukee kamerassa pientä joukkoa dtype-tyyppejä:

dtype

tavut

alue

uint8

1

0–255

int8

1

-128–127

uint16

2

0–65 535

int16

2

-32 768–32 767

float

4

IEEE 754 yksinkertainen tarkkuus

bool

1

True / False

int32- tai int64-tyyppiä ei ole, eikä OpenMV:n ulab-käännös ota käyttöön valinnaista complex-dtypeä.

Valitse tyyppi, joka vastaa dataa tuottanutta laitteistoa. 8-bittinen ADC-näyte haluaa uint8-tyypin; 12-bittinen ADC-näyte mahtuu uint16-tyyppiin; harmaasävykameran luminanssipikseli mahtuu uint8-tyyppiin – säästäen neljä kertaa sen RAM-muistin, jonka oletusarvoinen float maksaisi.

6.4.2. Oletusarvoinen dtype

Jokaisen Taulukoiden luominen-sivun konstruktorin oletusarvoinen dtype on float. Se on harvoin sitä, mitä sovellus haluaa sensoridataa käsitellessään. Anna dtype= eksplisiittisesti aina, kun luonnollinen leveys on pienempi:

sensor = np.array(samples, dtype=np.uint16)

Kokonaislukutaulukon uudelleenkäärintä ilman dtype=-argumenttia kopioi ja muuntaa liukuluvuksi, mikä maksaa sekä aikaa että RAM-muistia. Kun suorituskyvyllä on väliä, nimeä dtype.

6.4.3. Olemassa olevan taulukon dtype

dtype lukee taulukon dtypen takaisin sinä kokonaislukutyyppikoodina, jonka taulukko sisäisesti kantaa:

a = np.array([1, 2, 3], dtype=np.uint8)
print(a.dtype)            # 66 (the integer value of ``'B'``)

Tyyppikoodien kokonaisluvut vastaavat numpy-moduulissa esitettyjä vakioita – numpy.uint8, numpy.int8, numpy.uint16, numpy.int16, numpy.float, numpy.bool – joten dtypen vertaaminen moduulivakioon on tapa, jolla skripti haarautuu sen mukaan, mitä taulukko sisältää:

if a.dtype == np.uint8:
    ...  # uint8 branch

6.4.4. Tyypin laajennussäännöt

Kaksi eri dtype-tyyppistä taulukkoa voivat olla saman operaattorin operandeja. numpy valitsee tulostyypin lyhyen taulukon mukaan:

vasen

oikea

tulos

uint8

int8

int16

uint8

int16

int16

uint8

uint16

uint16

int8

int16

int16

int8

uint16

uint16

uint16

int16

float

mikä tahansa

float

float

uint16 / int16 -rivi laajenee suoraan float-tyyppiin, koska numpy-toteutuksella ei kamerassa ole 32-bittistä kokonaislukudtypeä.

Kun binäärioperaattorilla on toisella puolella Python-skalaari, skalaari muunnetaan pienimmän sopivan dtypen yksialkioiseksi taulukoksi: 123 muuttuu uint8-taulukoksi, -1000 muuttuu int16-tyypiksi, Pythonin float muuttuu float-tyypiksi.

6.4.5. Kokonaisluvun ylivuoto kiertyy

Kahden samaa kokonaislukudtypeä olevan taulukon operaatiot säilyttävät kyseisen dtypen, vaikka tulos vuotaisi yli. Muistinumero pudotetaan hiljaisesti pois:

a = np.array([200, 200], dtype=np.uint8)
b = np.array([100, 100], dtype=np.uint8)
print(a + b)

Tuloste:

array([44, 44], dtype=uint8)

Tulos on 300 mod 256 == 44. Kun välitulos tarvitsee enemmän aluetta kuin syötteen dtype sallii, tee tyyppimuunnos ensin:

c = np.array(a, dtype=np.uint16) + b
# array([300, 300], dtype=uint16)

Tämä sääntö koskee jokaista kokonaislukuoperaattoria – +, -, *, //, %, &, |, ^. Liukulukutaulukot eivät koskaan vuoda yli (ne laajenevat sen sijaan äärettömyyteen), joten tyyppimuunnostemppu on tarpeen vain kokonaislukutapauksessa.