M2 Dock開發(fā)板的MaixPY開發(fā)環(huán)境,自身支持獲取攝像頭視頻數(shù)據(jù),并對外提供MJPEG圖傳。
前幾天,研究了米爾MYD-YT507開發(fā)板USB攝像頭使用從入門到放棄,并成功實現(xiàn)了MJPEG推流圖傳。
于是,想著 M2 Dock 獲取 MJPEG推流數(shù)據(jù),接入到MaxiPY,顯示到屏幕上,以便于進一步的處理。
通過官方的在線手冊MaixPy3 image 模塊 - Sipeed Wiki了解到,通常創(chuàng)建一個image對象,使用的是Image.open()來打開一個文件。
最簡單的方法,可以在M2 Dock上,不間斷的獲取MJPEG的數(shù)據(jù),并保存到臨時文件,再使用 Image.open() 打開,然后再顯示到屏幕:
with open(tmp_file, "wb") as binary_file:
binary_file.write(jpg)
img = image.open(tmp_file)
display.show(img)
上述代碼中的jpg,即為獲取的MJPEG數(shù)據(jù)。
但這種方法,還需要進過一次保存文件的中轉(zhuǎn),多了一步操作。
如果能夠把獲取的數(shù)據(jù),直接給轉(zhuǎn)換成maix需要的數(shù)據(jù)格式,那就方便了。
進一步查閱官方手冊MaixPy3 image 模塊 - Sipeed Wiki,了解到maix的image對象,還支持如下的調(diào)用方式:
Image.load(data, [size = (240, 240) , [mode = "RGB"]])
在 python 對象中加載出一張圖像,會將 python 對象的數(shù)據(jù) copy 到 Image 對象內(nèi)部,如將 tobytes 的二進制數(shù)據(jù)重新恢復(fù)成 Image對象。
date可以是PIL對象, image.Image() 對象,bytes對象,numpy 對象.
當(dāng)data為bytes,numpy對象時,需要提供size和mode參數(shù).
返回 Image 對象,以便您可以使用 . 表示法調(diào)用另一個方法。
而這里的data,可以是多種來源,例如PIL。
PIL可以通過JPG的bianry流數(shù)據(jù),直接生成Image對象。
那么結(jié)合兩者,就可以跳過文件保存再調(diào)用的步驟了:
bytes_stream = BytesIO(jpg)
pimg = Image.open(bytes_stream)
img = image.load(pimg)
display.show(img)
最終,經(jīng)過反復(fù)嘗試,實現(xiàn)了M2 Dock的MaxiPY,獲取MJPEG推流數(shù)據(jù)并顯示到屏幕。
完整的代碼如下:
import numpy as np
import platform
if platform.uname().node == "sipeed":
from io import BytesIO
from PIL import Image
from maix import camera, mjpg, utils, display, image
else:
import cv2
READ_TYPE = "socket" # url socket
MJPEG_HOST = "192.168.2.207"
MJPEG_PORT = 8080
MJPEG_QUERY = "/?action=stream"
def img_data_show(jpg):
global img_bytes
global tmp_file
global is_sipeed
global BytesIO
global Image
global np
global image
global display
if is_sipeed:
if True:
bytes_stream = BytesIO(jpg)
pimg = Image.open(bytes_stream)
img = image.load(pimg)
display.show(img)
else:
with open(tmp_file, "wb") as binary_file:
binary_file.write(jpg)
img = image.open(tmp_file)
display.show(img)
else:
img = cv2.imdecode(np.frombuffer(
jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
cv2.imshow('i', img)
if cv2.waitKey(1) == 27:
exit(0)
def img_data_match(chunk):
global img_bytes
global tmp_file
global is_sipeed
global BytesIO
global Image
global np
global image
global display
global img_data_show
img_bytes += chunk
a = img_bytes.find(b'??')
b = img_bytes.find(b'?ù')
if a != -1 and b != -1:
jpg = img_bytes[a:b+2]
img_bytes = img_bytes[b+2:]
img_data_show(jpg)
img_bytes = b''
tmp_file = "/tmp/test.jpg"
is_sipeed = platform.uname().node == "sipeed"
print("Connect to %s:%d with %s on %s" % (MJPEG_HOST, MJPEG_PORT, READ_TYPE, platform.uname().node))
if READ_TYPE == "url":
import requests
MJPEG_URL = "http://%s:%s%s" % (MJPEG_HOST, MJPEG_PORT, MJPEG_QUERY)
r = requests.get(MJPEG_URL, stream=True)
if(r.status_code == 200):
print("connect success!")
for chunk in r.iter_content(chunk_size=1024):
img_data_match(chunk)
else:
print("Received unexpected status code {}".format(r.status_code))
elif READ_TYPE == "socket":
import socket
client = socket.socket() # 創(chuàng)建socket套接字
ret = client.connect((MJPEG_HOST, MJPEG_PORT)) # 狀態(tài)位,判定是否連接成功
request_url = "GET %s HTTP/1.1
Host:%s
Connection:Close
" % (
MJPEG_QUERY, MJPEG_HOST)
if(ret == -1): # 連接失敗,退出程序
print("connet error!")
exit(-1)
else: # 連接成功
print("connect success!")
client.send(request_url.encode()) # 發(fā)送socket請求,開始接收數(shù)據(jù)
chunk = client.recv(1024) # 第一個recv返回信息,跟圖片無關(guān)
chunk = client.recv(1024) # 這個信息開始跟圖片有關(guān)系,放到接收變量里
while chunk: # 判斷是否還有信息
img_data_match(chunk)
chunk = client.recv(1024) # 繼續(xù)接收
上述代碼中,包含如下的部分:
- 獲取MJPEG數(shù)據(jù)時,可以試用python的request模塊,或者使用socket模塊,后者效率更高
- 獲取到MJPEG數(shù)據(jù)后,自動分析其中的JPG數(shù)據(jù)幀,一旦檢測到,則進行顯示處理
- 顯示處理部分,會自動區(qū)分是在電腦上,還是在M2 Dock上
- 如果是在電腦上,則使用cv2進行處理顯示,如果需要退出可以按ESC按鍵
-
如果是在M2 Dock上,則使用
BytesIO
來 獲取的數(shù)據(jù)轉(zhuǎn)換為二進制流,然后提供給PIL生成進行處理生成Image對象,再提供給display模塊顯示。
上述源碼,提供在M2_Dock: M2 Dock學(xué)習(xí)研究與實例分享 (gitee.com)。
最終具體的呈現(xiàn)效果,可以查看附件的視頻。
-
開發(fā)板試用
+關(guān)注
關(guān)注
3文章
301瀏覽量
2343
發(fā)布評論請先 登錄
【RA-Eco-RA4M2開發(fā)板評測】UART測試實驗

免費丨米爾 STM32MP257開發(fā)板有獎試用

THS8135進行YUV輸出,如何配置M1,M2,還有SYNC_T這些信號?
THS8135不需要外部再引入SYNC/BLANK信號,M1/M2/CLK & SYNC/SYNC_T/BLANK信號應(yīng)該怎樣處理?
追加名額丨米爾瑞芯微RK3576開發(fā)板有獎試用

ICY DOCK M.2轉(zhuǎn)U.2 SSD轉(zhuǎn)接盒如何重新定義M.2 NVMe SSD

評論