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 |
|---|---|---|
|
1 |
0–255 |
|
1 |
-128–127 |
|
2 |
0–65 535 |
|
2 |
-32 768–32 767 |
|
4 |
IEEE 754 yksinkertainen tarkkuus |
|
1 |
|
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 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mikä tahansa |
|
|
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.