13.3.1.3. Prijenos sličica u stvarnom vremenu¶
Skripta koja snima sličice na kameri može svaku sličicu prenositi natrag do glavnog računala preko USB-a. Obrazac čine dva poziva na instanci openmv.Camera: streaming() za uključivanje ili isključivanje prijenosa te read_frame() za dohvaćanje sljedeće sličice iz kanala.
13.3.1.3.1. Minimalna petlja za prijenos i prikaz¶
Skripta na strani kamere uobičajena je petlja snimanja; novo je to da glavno računalo otvara prijenos i čita rezultat natrag:
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 neprekidno snima sličice; glavno računalo dohvaća svaku od njih iz međuspremnika prijenosa kako pristiže. Kamera prepisuje međuspremnik prijenosa pri svakoj novoj snimci, pa će glavno računalo koje očitava sporije nego što kamera snima tiho ispustiti sličice – a to je upravo ispravno ponašanje za scenarije nalik pregledniku.
13.3.1.3.2. Rječnik sličice (frame dict)¶
read_frame() vraća ili None (nijedna sličica ne čeka) ili dict s pet unosa:
Ključ |
Značenje |
|---|---|
|
Širina sličice u pikselima. |
|
Visina sličice u pikselima. |
|
Identifikator formata piksela koji je kamera prijavila (cijeli broj iz konstanti |
|
Za komprimirane formate (JPEG, PNG), veličina komprimirane slike u bajtovima. Ne koristi se za nekomprimirane formate. |
|
Sličica kao međuspremnik |
|
Bajtovi koje je kamera poslala preko USB-a prije dekodiranja. Korisno za stvarni izračun propusnosti. |
Paket pretvara izvorni format kamere (GRAYSCALE, RGB565, JPEG) u RGB888 prije vraćanja, pa glavno računalo nikada ne mora samo raditi s bitno spakiranim RGB565 ili putanjom dekompresije JPEG-a. Sličice u sivim tonovima vraćaju se s vrijednošću svjetline (luma) repliciranom u sva tri kanala.
Međuspremnik data raspoređen je redak po redak, od vrha prema dnu; izravno ga predati biblioteci za prikaz ili spremiti kao sirovu RGB datoteku radi bez ikakvog daljnjeg presloživanja.
13.3.1.3.3. Sirovi način prijenosa¶
Prema zadanom kamera JPEG-komprimira svaku snimljenu sličicu prije nego što je smjesti u kanal prijenosa, a read_frame() je dekomprimira na glavnom računalu. Na kamerama bez hardverske podrške za JPEG, softverska kompresija najsporiji je korak u petlji. Prosljeđivanje raw=True preskače je:
cam.streaming(True, raw=True, resolution=(320, 240))
Kamera tada šalje međuspremnik piksela nekomprimiran. Nekomprimirane sličice mnogo su veće od svojih JPEG ekvivalenata, pa kamera svaku snimljenu sličicu smanjuje kako bi stala u kanal prijenosa prije slanja; argument resolution=(width, height) postavlja taj ciljani format. Glavno računalo i dalje prima RGB888 u polju data – paket pretvara iz bilo kojeg formata piksela koji je kamera prijavila u format.
13.3.1.3.4. Neka događaji upravljaju petljom¶
Petlja s očitavanjem koja poziva read_frame() brže nego što kamera proizvodi sličice provodi većinu vremena dobivajući None natrag. Kada glavno računalo ima i druge poslove (sučelje za ažuriranje, druge kanale za očitavanje), read_status() jeftinija je provjera: vraća rječnik koji svako registrirano ime kanala preslikava u logičku vrijednost „podaci su spremni”:
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 ...
Ovo je oblik petlje koji koristi sam CLI preglednik.
13.3.1.3.5. Zaustavljanje prijenosa¶
Pozovite streaming() s enable=False za zaustavljanje. Kamera nastavlja izvoditi svoju skriptu, ali više ne puni međuspremnik prijenosa; read_frame() od te točke nadalje jednostavno vraća None. Poziv stop() čini isto implicitno zaustavljanjem skripte.