PC基于wifi采用UDP协议实现ESP32无线图传显示在1.44寸屏幕

开发环境:Ubuntu16.04
ESP32:Arduino
PC图传:Python3.6.9

首先上python代码

import socket
import cv2
import numpy as np


img = cv2.imread('./picture.jpg')  #读取图像
# 检测图片的象素大小
sp = img.shape
print(sp[0], sp[1], sp[2]) # sp[0] height sp[1] width
height = img.shape[0]
width = img.shape[1]
if (sp[0] != 128)&(sp[1] != 128):
    img = cv2.resize(img, (int(128), int(128)))  # 修改象素大小为128*128
    # cv2.imshow("pic", img)
print(img.shape)
image_arr = [0 for i in range(128*128)]
image_R = [0 for i in range(128*128)]
image_G = [0 for i in range(128*128)]
image_B = [0 for i in range(128*128)]
# print(img[0][0]) # 顺序是BGR ,img[y][x]
# 取模,RGB888 变为 RGB565  RGB都取高位
for i in range(128):
    for j in range(128):
        image_R[i * 128 + j] = img[i][j][2] >> 3
        image_G[i * 128 + j] = img[i][j][1] >> 2
        image_B[i * 128 + j] = img[i][j][0] >> 3
for i in range(128*128):
    image_arr[i] = (image_R[i] << 11) | (image_G[i] << 5) | (image_B[i])



# 创建socket对象
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # AF_INET ipv4协议 SOCK_DGRAM  udp模式
host = socket.gethostname()  # 获取本地计算机名
ip = '192.168.2.109'
port = 9000  # 设置端口号
s.bind((ip, port))  # 绑定本地ip和端口
print("udp配置完成")
print("udp ip ", ip, " port", port)


value = 1
for i in range(128*128):
    s.sendto(int(image_arr[i]).to_bytes(2, 'big'), ('192.168.2.105', 9000))
    print(int(image_arr[i]).to_bytes(2, 'big'))
    while True:
        data = s.recv(1024)
        if data == value.to_bytes(1,'big'):
            break
s.close()

该Python代码的主要功能就是把图片改为128*128大小的565象素格式的图片,能进行UDP通讯,本人是Python小白,有些地方我感觉可以在改进的,尤其是通过udp,每一次只能传送两个字节。下面的代码由于PC发送的太快导致ESP32接收不过来,所以我采用应答的方式保证每个象素点的值能被ESP32接收。如果能改善的话,我感觉可以实现视频传输了。
注:
在888象素格式转化565格式的时候,一定要注意,是用RGB高5位和高6位
在python opencv中读出的图像数组顺序是BGR!!

下面是esp32代码

#include     // Core graphics library
#include  // Hardware-specific library
#include 
#include 
#include 

#define TFT_CS     5
#define TFT_RST    16
#define TFT_DC     17
#define TFT_SCLK  18
#define TFT_MOSI  23
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);
float p = 3.1415926;

// WiFi network name and password:
const char * networkName = "xxxxx";
const char * networkPswd = "xxxxx";


const char * udpAddress = "192.168.2.109";
const int udpPort = 9000;

//Are we currently connected?
boolean connected = false;

//The udp library class
WiFiUDP udp;

uint8_t frame[128];
uint8_t udp_frame[32768];
uint16_t image_frame[16384];
int framesize = 0;
int size = 0;
uint8_t response[2] = {1,2};

void draw_picture(uint16_t* buff)
{
    int i =0;
    int j = 0;
    for(i=0;i<128;i++)
        for(j=0;j<128;j++)
            tft.drawPixel(j,i,buff[j+128*i]);
}


void connectToWiFi(const char * ssid, const char * pwd){
  Serial.println("Connecting to WiFi network: " + String(ssid));

  // delete old config
    WiFi.disconnect(true);
  //register event handler
    WiFi.onEvent(WiFiEvent);

  //Initiate connection
    WiFi.begin(ssid, pwd);

    Serial.println("Waiting for WIFI connection...");
}

//wifi event handler
void WiFiEvent(WiFiEvent_t event){
    switch(event) {
      case SYSTEM_EVENT_STA_GOT_IP:
          //When connected set
          Serial.print("WiFi connected! IP address: ");
          Serial.println(WiFi.localIP());
          //initializes the UDP state
          //This initializes the transfer buffer
          udp.begin(WiFi.localIP(),udpPort);
          connected = true;
          break;
      case SYSTEM_EVENT_STA_DISCONNECTED:
          Serial.println("WiFi lost connection");
          connected = false;
          break;
      default: break;
    }
}


void setup(){

  Serial.begin(115200);

  tft.initR(INITR_144GREENTAB);   // initialize a ST7735S chip, black tab

  //Connect to the WiFi network
  connectToWiFi(networkName, networkPswd);
}

void loop(){
    int i = 0;

    if(connected){
        int num = udp.parsePacket();
        if(udp.read(frame,128)){
            for(i=0;i<num;i++){
                udp_frame[i+framesize] = frame[i];
            }
            framesize += 2;
            udp.beginPacket(udpAddress,udpPort);
            udp.write(response,1);
            udp.endPacket();
        }
        else if(framesize == 32768)
        {

            for(i=0;i<32768;i++)
            {
                image_frame[size] = (udp_frame[i]<<8) | (udp_frame[i+1]);
                Serial.println(image_frame[size]);
                size++;
                i++;
            }

            draw_picture(image_frame);
            framesize = 0;
            size = 0;

        }
    }
}

最后展示一下结果:
PC基于wifi采用UDP协议实现ESP32无线图传显示在1.44寸屏幕_第1张图片
使用的话代码直接用,把任意一个大于128×128的图片放在Python工程,设置好端口和ip就可以实现了。

你可能感兴趣的:(udp,opencv,网络协议)