13.3.1.3. Kehysten suoratoisto¶
Skripti, joka kaappaa kehyksiä kamerassa, voi suoratoistaa jokaisen kehyksen takaisin isäntäkoneelle USB:n kautta. Kaava on kaksi kutsua openmv.Camera -instanssille: streaming() kytkee suoratoiston päälle tai pois, ja read_frame() noutaa seuraavan kehyksen kanavasta.
13.3.1.3.1. Pienin mahdollinen suoratoisto- ja näyttösilmukka¶
Kameran puolen skripti on tavanomainen snapshot-silmukka; uutta on se, että isäntäkone avaa suoratoiston ja lukee tuloksen takaisin:
from openmv import Camera
script = """
import csi
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QVGA)
while True:
csi0.snapshot()
"""
with Camera('/dev/ttyACM0') as cam:
cam.stop()
cam.exec(script)
cam.streaming(True)
while True:
if frame := cam.read_frame():
print(f"{frame['width']}x{frame['height']}, "
f"{frame['raw_size']} bytes")
Kamera kaappaa kehyksiä jatkuvasti; isäntäkone noutaa jokaisen niistä suoratoistopuskurista sitä mukaa kun ne saapuvat. Kamera korvaa suoratoistopuskurin jokaisen uuden tilannekuvan yhteydessä, joten isäntäkone, joka pollaa hitaammin kuin kamera kaappaa, pudottaa kehyksiä huomaamatta – mikä on oikea toimintatapa katselutyyppisille käyttötapauksille.
13.3.1.3.2. Kehys-dict¶
read_frame() palauttaa joko None (yhtään kehystä ei ole odottamassa) tai dict-sanakirjan, jossa on viisi merkintää:
Avain |
Merkitys |
|---|---|
|
Kehyksen leveys pikseleinä. |
|
Kehyksen korkeus pikseleinä. |
|
Kameran ilmoittama pikseliformaatin tunniste (kokonaisluku kameran |
|
Pakatuille formaateille (JPEG, PNG) pakatun kuvan koko tavuina. Pakkaamattomille formaateille ei käytössä. |
|
Kehys |
|
Tavut, jotka kamera lähetti USB:n kautta ennen purkua. Hyödyllinen todellisen läpäisykyvyn laskennassa. |
Paketti muuntaa kameran natiiviformaatin (GRAYSCALE, RGB565, JPEG) RGB888-muotoon ennen palauttamista, joten isäntäkoneen ei koskaan tarvitse käsitellä bittipakattua RGB565:tä tai JPEG-purkupolkua itse. Harmaasävykehykset palautuvat siten, että luma-arvo on kopioitu kaikkiin kolmeen kanavaan.
data-puskuri on järjestetty rivi riviltä, ylhäältä alas; sen syöttäminen suoraan näyttökirjastolle tai tallentaminen raakana RGB-tiedostona toimii ilman mitään lisäjärjestelyä.
13.3.1.3.3. Raaka suoratoistotila¶
Oletuksena kamera JPEG-pakkaa jokaisen kaapatun kehyksen ennen sen sijoittamista suoratoistokanavaan, ja read_frame() purkaa pakkauksen isäntäkoneella. Kameroissa, joissa ei ole laitteistopohjaista JPEG-tukea, ohjelmistopakkaus on silmukan hitain vaihe. raw=True -arvon välittäminen ohittaa sen:
cam.streaming(True, raw=True, resolution=(320, 240))
Kamera lähettää tällöin pikselipuskurin pakkaamattomana. Pakkaamattomat kehykset ovat paljon suurempia kuin niiden JPEG-vastineet, joten kamera skaalaa jokaisen kaapatun kehyksen pienemmäksi mahtuakseen suoratoistokanavaan ennen lähettämistä; resolution=(width, height) -argumentti asettaa tämän tavoitteen. Isäntäkone vastaanottaa edelleen RGB888:n data-kentässä – paketti muuntaa mistä tahansa pikseliformaatista, jonka kamera ilmoitti format-kentässä.
13.3.1.3.4. Tapahtumien annetaan ohjata silmukkaa¶
Pollaussilmukka, joka kutsuu read_frame() -metodia nopeammin kuin kamera tuottaa kehyksiä, viettää suurimman osan ajastaan saaden takaisin None. Kun isäntäkoneella on myös muuta tehtävää (käyttöliittymä päivitettävänä, muita kanavia pollattavana), read_status() on edullisempi tarkistus: se palauttaa sanakirjan, joka kuvaa jokaisen rekisteröidyn kanavan nimen totuusarvoon ”data on valmiina”:
while True:
status = cam.read_status()
if status.get('stream'):
frame = cam.read_frame()
# ... process the frame ...
if status.get('stdout'):
text = cam.read_stdout()
print(text, end='')
if status.get('my_channel'):
data = cam.channel_read('my_channel')
# ... process custom-channel data ...
Tämä on silmukan muoto, jota CLI-katseluohjelma itse käyttää.
13.3.1.3.5. Suoratoiston pysäyttäminen¶
Kutsu streaming() -metodia arvolla enable=False pysäyttääksesi. Kamera jatkaa skriptinsä suorittamista mutta ei enää täytä suoratoistopuskuria; read_frame() palauttaa siitä lähtien vain None. stop() -metodin kutsuminen tekee saman implisiittisesti pysäyttämällä skriptin.