python使用opencv播放視訊併傳送到串列埠,讓51顯示

PpgpOs發表於2018-09-12

上一篇說了怎麼處理圖片,這次用視訊。opencv不能放聲音

第一步:開啟視訊

import serial
import cv2

ser = serial.Serial('com2', 57600, timeout=None)    # 開啟串列埠com2,57600bps,超時設定為無
print(ser)  # 列印串列埠資訊
print(ser.isOpen())  # 檢查串列埠是否被開啟
# 使用串列埠就寫

vid = cv2.VideoCapture()
vid.open('e:/badapple.mp4')    # 載入e盤根目錄下視訊
while True:
    vidstatu, frame = vid.read()    # vidstatu=False則播放結束,True為正常,frame為幀資料
    if not vidstatu:
        break
    cv2.imshow('bad', frame)  # 播放
    cv2.waitKey(25)           # 不加延時放不了,opencv裡用的很多

opencv是提取視訊每一幀的資料播放,類似播放膠捲視訊

延時大概就是25ms,改變延時時間可以快 / 慢播放速度

第二步:改變視訊大小,或者說解析度吧。再轉灰度圖播放

frainfo = frame.shape   # 讀取幀資料資訊
va1 = frainfo[0] / 64
width = int(frainfo[1] / va1)   # 加int,捨去小數。計算高度為64時,等比例寬度是多少
high = int(frainfo[0] / va1)
print('寬:{0},高:{1}'.format(width,high))
dst = cv2.resize(frame, (width, high))  # 縮放,width和high只能取整數
gray_lwpCV = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY)  # 轉灰度圖
cv2.imshow('bad', frame)
cv2.waitKey(25)           

第三步:轉化資料 

oled = [[0 for i in range(128)] for i in range(8)]  # 建立[8][128]的列表

for i in range(high):
    Ic = i % 8
    for j in range(width):
        if gray_lwpCV[i, j] < 128:  # [高, 寬]
             oled[i // 8][j] |= 0x01 << Ic

這裡沒提前轉黑白,因為判斷是否小於128就已經做了這件事,上一篇裡也可以不要 

第四步:傳送資料

for i in range(8):
    str1 = b'start' + bytes.fromhex('%02x' % i)  # 字串(str型別,就是Unicode解碼16進製出來的)編碼成bytes(就是ascii碼),把被解碼的16進位制重新編碼回去。b'0'被轉成\x30傳送,\x是python的16進位制標識碼,和0x一樣
    ser.write(str1)    # 只能傳送str
    for j in range(128):
        hhex = '%02x' % oled[i][j]  # 以16進製表示,不帶前面的‘0x’,輸出一個字串,不足兩個字元前面補0如,int型別的48,轉成str型別的'30'
        ser.write(bytes.fromhex(hhex))  # bytes.fromhex(hhex)返回一個 b'n'字串,n為該16進位制對應的ascii碼,如b'0',hhex為字串,hhex='30'
        if j == 127:
           while True:
               ll = ser.read(5)    # 寫幾就接收幾個,不足就一直等,不填每次收一個位元組就返回資料
               if ll == b'hello':  # 讀到的是c51發的16進位制,對比時也要用16進位制對比
                   break

這裡我在傳送每一行資料之前傳送了'startx',x為16進位制的0~7,還有在底下的,當傳送完128次列資料後等待微控制器傳送'hello'再繼續。因為一直髮送資料,量又大,保不齊就丟了一個,傳送start(0~7),就是防止一個資料丟了,顯示全錯位,強制修正

在微控制器裡建了128位元組的陣列,判斷串列埠資訊,比如收到'start5',這裡的5是0x05,直接判斷接下來收到的資料應該在哪一行顯示

當python把資料傳送完以後,等待微控制器傳送'hello',這個時候微控制器在操作顯示,當8x128陣列裡的資料全部顯示完了後,傳送'hello',python才繼續下一行的傳送

u8 ix=0;
u8 iy=0,uy=0;
u8 xdata bad[128]=0;
u8 code str1[]={"start"};
u8 ca=0;bit fc=0;bit st=0;
bit iflg=0;
void Interrupt4() interrupt 4	
{
	if(RI)
	{
		RI=0;	
		if(iflg==0)//處理start
		{
			if(fc==1)uy=SBUF,fc=0,ca=0,iflg=1;    // fc置1後,再次接收資料,是幾uy就等於幾,並開始接收顯示資料			
                        if(SBUF==str1[ca]){ca++;if(ca>=5)fc=1;}	// 收到完整start後fc置1
			else ca=0;
		}else//處理顯示資料
		{
			bad[ix]=SBUF;接受顯示資料
			ix++;
			if(ix>=128)
			{	
				ES=0;    //關閉串列埠中斷,可以不用
				CS1=1,CS2=0;
				WriteCom(0xb8+uy),WriteCom(0x40);
				for(ix=0;ix<128;ix++)
				{
					if(ix==64)CS1=0,CS2=1,WriteCom(0xb8+uy),WriteCom(0x40);
					WriteData(bad[ix]);
				}
				ix=0;iflg=0;	
				SendString("hello");    //顯示完一行後傳送'hello'
                                ES=1;
			}		
		}		
	}
}

有問題是自然的,討論問題,可能解決速度不是最快的,但是是最好的方法

共同提高比個體強大有意義的多

https://pan.baidu.com/s/1I39Y1mU-_L19WgbwNeINMg

相關文章