13.3.1.3. Képkockák streamelése¶
A kamerán képkockákat rögzítő szkript minden képkockát visszastreamelhet a gazdagépre USB-n keresztül. A minta két hívásból áll az openmv.Camera példányon: az streaming() a stream be- vagy kikapcsolására, az read_frame() pedig a következő képkocka kiolvasására a csatornából.
13.3.1.3.1. Egy minimális streamelő és megjelenítő ciklus¶
A kamera oldali szkript a szokásos snapshot ciklus; az új az, hogy a gazdagép megnyitja a streamet és visszaolvassa az eredményt:
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")
A kamera folyamatosan rögzíti a képkockákat; a gazdagép mindegyiket kiveszi a stream pufferből, amint az megérkezik. A kamera minden új pillanatkép esetén felülírja a stream puffert, így az a gazdagép, amely lassabban kérdez le, mint ahogy a kamera rögzít, csendben eldobja a képkockákat – megjelenítő jellegű felhasználási esetekben éppen ez a helyes viselkedés.
13.3.1.3.2. A képkocka dict¶
Az read_frame() vagy None értéket ad vissza (nincs várakozó képkocka), vagy egy öt bejegyzést tartalmazó dict típust:
Kulcs |
Jelentés |
|---|---|
|
A képkocka szélessége képpontban. |
|
A képkocka magassága képpontban. |
|
A kamera által deklarált képpontformátum-azonosító (egész szám a kamera |
|
Tömörített formátumok (JPEG, PNG) esetén a tömörített kép mérete bájtban. Tömörítetlen formátumoknál nincs használatban. |
|
A képkocka RGB888 formátumú |
|
A kamera által dekódolás előtt USB-n keresztül küldött bájtok száma. Hasznos a tényleges átviteli teljesítmény kiszámításához. |
A csomag a kamera natív formátumát (GRAYSCALE, RGB565, JPEG) RGB888 formátumra alakítja a visszaadás előtt, így a gazdagépnek soha nem kell foglalkoznia a bit-csomagolt RGB565 vagy JPEG-kicsomagolási útvonallal. A szürkeárnyalatos képkockák a luma értéknek mindhárom csatornára másolt változatával térnek vissza.
A data puffer soronként, felülről lefelé van elrendezve; egyenesen egy megjelenítő könyvtárnak átadva vagy nyers RGB fájlként mentve minden további átrendezés nélkül működik.
13.3.1.3.3. Nyers streamelési mód¶
Alapértelmezés szerint a kamera JPEG-tömörítéssel látja el minden rögzített képkockát, mielőtt a stream csatornába helyezné, és az read_frame() a gazdagépen kicsomagolja. Hardveres JPEG-támogatás nélküli kamerákon a szoftveres tömörítés a ciklus leglassabb lépése. A raw=True megadása kihagyja ezt:
cam.streaming(True, raw=True, resolution=(320, 240))
Ekkor a kamera tömörítetlenül küldi a képpontpuffert. A tömörítetlen képkockák sokkal nagyobbak JPEG megfelelőiknél, ezért a kamera minden rögzített képkockát lekicsinyít, hogy beleférjen a stream csatornába, mielőtt elküldené; a resolution=(width, height) argumentum állítja be ezt a célt. A gazdagép továbbra is RGB888 formátumot kap a data mezőben – a csomag konvertál abból a képpontformátumból, amelyet a kamera a format mezőben jelentett.
13.3.1.3.4. Hagyjuk, hogy események vezéreljék a ciklust¶
Egy lekérdező ciklus, amely gyorsabban hívja meg az read_frame() metódust, mint ahogy a kamera képkockákat állít elő, idejének nagy részét azzal tölti, hogy None értéket kap vissza. Amikor a gazdagépnek más teendője is van (frissítendő felhasználói felület, más lekérdezendő csatornák), az read_status() az olcsóbb ellenőrzés: egy dict típust ad vissza, amely minden regisztrált csatornanevet egy logikai „az adat készen áll” értékhez rendel:
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 ...
Ez a ciklusforma az, amelyet maga a CLI megjelenítő használ.
13.3.1.3.5. A stream leállítása¶
Hívd meg az streaming() metódust enable=False értékkel a leállításhoz. A kamera tovább futtatja a szkriptjét, de már nem tölti fel a stream puffert; az read_frame() ettől kezdve csak None értéket ad vissza. Az stop() meghívása ugyanezt teszi implicit módon, a szkript leállításával.