電腦端Python程序作為視頻數(shù)據(jù)的服務(wù)器,借助OpenCV實(shí)時(shí)讀取視頻幀,并進(jìn)行二值圖像轉(zhuǎn)換,尺寸調(diào)整,再將二值圖像轉(zhuǎn)為數(shù)組,并以二進(jìn)制形式的數(shù)據(jù)通過socket方式無(wú)線發(fā)送給ESP8266。
ESP8266采用Arduino IDE編程,借助U8g2庫(kù),將圖像數(shù)據(jù)實(shí)時(shí)顯示到OLED屏幕中。
1 ESP8266端視頻幀接收與播放程序
ESP8266作為socket客戶端,接收服務(wù)端發(fā)送的圖像幀數(shù)據(jù),進(jìn)行顯示。
ESP8266使用Arduino IDE環(huán)境進(jìn)行開發(fā)。
1.1 WIFI初始化與服務(wù)器連接
#define IP "192.168.5.100"
#define PORT 8080
void initWiFi()
{
Serial.print("Connecting WiFi...");
WiFi.mode(WIFI_STA); //配置WIFI為Station模式
WiFi.begin(ssid, pass); //傳入WIFI熱點(diǎn)的ssid和密碼
while (WiFi.status() != WL_CONNECTED) //等待連接成功
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP()); //打印自己的IP地址
client.connect(IP, PORT);
}
1.2 視頻顯示主循環(huán)
uint8_t testb[1024] = {};
void loop()
{
//Serial.println("hello esp8266");
delay(10);
while (client.available())
{
delay(12);
client.read(testb, 1024);
u8g2.firstPage();
do {
u8g2.drawXBM(0, 0, 128, 64, testb);
} while (u8g2.nextPage());
}
}
2電腦端視頻編碼發(fā)送程序
電腦端作為socket服務(wù)器端,將視頻幀數(shù)據(jù)發(fā)送出去。
電腦端采用Python3編程,借助OpenCV實(shí)現(xiàn)視頻的讀取與圖像數(shù)據(jù)格式轉(zhuǎn)換。
2.1 主程序
程序的基本思想是:
利用OpenCV讀取視頻文件
對(duì)視頻幀的圖像,進(jìn)行尺寸修改
對(duì)圖像進(jìn)行二值化處理
將二值圖像轉(zhuǎn)換為數(shù)組
將數(shù)組通過socket發(fā)送出去
video_path="badapple_320240_xvid.mp4"
def PlayVideo(video_path, client):
endian = 'L'
color_reverse = 'false'
c = 0#累計(jì)幀數(shù)
timeF = 8#隔x幀截一次圖
video = cv2.VideoCapture(video_path) #打開視頻
player = MediaPlayer(video_path) #打開音頻
while True:
grabbed, frame= video.read()
audio_frame, val = player.get_frame()
if not grabbed:
print("End of video")
break
if cv2.waitKey(28) & 0xFF == ord("q"):
break
cv2.imshow("Video", frame)
if val != 'eof' and audio_frame is not None:
img, t = audio_frame
if (c % timeF == 0): # 每隔timeF幀進(jìn)行存儲(chǔ)操作
frame = cv2.resize(frame,(128,64))#調(diào)整尺寸
frame = binary_image(frame)#二值化
matrix = img_to_matrix(frame, endian, color_reverse)
data = bytes(matrix)
client.send(data)
c = c + 1
#time.sleep(0.2)
#cv2.waitKey(1)
video.release()
cv2.destroyAllWindows()
###############
client = 0
client = socket_start()
PlayVideo(video_path, client)
2.2 圖像轉(zhuǎn)為數(shù)組
利用OpenCV,將圖像轉(zhuǎn)為黑白圖像:
def binary_image(image):#將圖像處理為二值化的程序
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) #把輸入圖像灰度化
h, w =gray.shape[:2]
m = np.reshape(gray, [1,w*h])
mean = m.sum()/(w*h)
ret, binary = cv2.threshold(gray, mean, 255, cv2.THRESH_OTSU)
return binary
然后再轉(zhuǎn)為數(shù)組:
def img_to_matrix(frame, endian, color_reverse):
width = frame.shape[1] #128
height = frame.shape[0] #64
if endian == 'B':
byte_reverse = True
else:
byte_reverse = False
if color_reverse == 'true':
color_reverse = True
else:
color_reverse = False
unalign = 0
matrix = list()
if (width%8) != 0:
unalign = 1
for i in range(0, height): #64
for j in range(0, (width//8)+unalign): #128/8=16
v = 0x00
rs = 8*j
re = 8*(j+1)
if re > width:
re = width
for k in range(rs, re):
if frame[i, k] != 0:
if not byte_reverse:
v |= (0x01 << (k%8))
else:
v |= (0x01 << (7-(k%8)))
if color_reverse:
v ^= 0xff
matrix.append(v)
return matrix
2.3 開啟socket服務(wù)
def socket_start():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostbyname(socket.gethostname())
port = 8080
host = '192.168.5.100'
print(host)
print(port)
s.bind((host,port))
s.listen(5)
print('等待客戶端連接中…')
client,client_address = s.accept()
print('新連接')
client_IP = str(client_address[0])
print('IP:'+client_IP)
client_port = str(client_address[1])
print('Port:' + client_port)
return client
3 測(cè)試效果
https://www.bilibili.com/video/BV11S4y1S7ir
4 總結(jié)
本篇介紹ESP8266在OLED上播放視頻,包括ESP8266端的圖像接收與顯示程序,與電腦端的Python讀取視頻并進(jìn)行編碼與數(shù)據(jù)發(fā)送程序。
-
嵌入式
+關(guān)注
關(guān)注
5082文章
19126瀏覽量
305198 -
WIFI
+關(guān)注
關(guān)注
81文章
5297瀏覽量
203717 -
ESP8266
+關(guān)注
關(guān)注
50文章
962瀏覽量
45008
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論