esp32cam与python的同步udp通信

python

import socket
import threading
import numpy as np
import cv2
import time

def send():
    while True:
        s.sendto("camoff".encode(), ('192.168.2.204', 8081))
        time.sleep(1)

def recv():
    temp_data = b''
    millis1 = int(round(time.time() * 1000))
    while True:
        data, addr = s.recvfrom(1460)
        if data[0:len(begin_data)] == begin_data:
            temp_data = temp_data + data[len(begin_data):]
            while True:
                data, addr = s.recvfrom(1460)
                if end_data == data[-10:]:
                    temp_data = temp_data + data[0:len(data) - 10]
                    break
                temp_data = temp_data + data
            # print(temp_data)
            try:
                receive_data = np.frombuffer(temp_data, dtype='uint8')  # 将获取到的字符流数据转换成1维数组
                r_img = cv2.imdecode(receive_data, cv2.IMREAD_COLOR)  # 将数组解码成图像
                millis2 = int(round(time.time() * 1000))
                millis = millis2 - millis1
                fps = (1000 // millis)
                cv2.putText(r_img, "FPS:" + str(fps), (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
                cv2.imshow('frame', r_img)
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break
                print("接收到的数据包:" + str(len(temp_data)))  # 显示该张照片数据大小
                temp_data = b''  # 清空数据 便于下一章照片使用
                millis1 = millis2
            except Exception as e:
                print("Frame Data Error!")
        else:
            print(data.decode())
# 创建UDP服务器
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
addr = ('192.168.2.200', 8081)
s.bind(addr)
begin_data = b'FrameBegin'
end_data = b'FrameOverr'
t0 = threading.Thread(target=recv)
t0.start()
t1 = threading.Thread(target=send)
t1.start()

ESP32Cam

#include "esp_camera.h"
#include <WiFi.h>
#include <WiFiUdp.h> //引用以使用UDP
#include <vector>

const char *ssid = "dsx_zj";
const char *password = "dsxbs725";
WiFiUDP Udp;                      //创建UDP对象
unsigned int localUdpPort = 8081; //本地端口号
#define maxcache 1430
bool is_tran_camera =  false; //是否传输视频数据
String cam_on = "camon";  
String cam_off = "camoff";
#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27

#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22

static camera_config_t camera_config = {
    .pin_pwdn = PWDN_GPIO_NUM,
    .pin_reset = RESET_GPIO_NUM,
    .pin_xclk = XCLK_GPIO_NUM,
    .pin_sscb_sda = SIOD_GPIO_NUM,
    .pin_sscb_scl = SIOC_GPIO_NUM,
    
    .pin_d7 = Y9_GPIO_NUM,
    .pin_d6 = Y8_GPIO_NUM,
    .pin_d5 = Y7_GPIO_NUM,
    .pin_d4 = Y6_GPIO_NUM,
    .pin_d3 = Y5_GPIO_NUM,
    .pin_d2 = Y4_GPIO_NUM,
    .pin_d1 = Y3_GPIO_NUM,
    .pin_d0 = Y2_GPIO_NUM,
    .pin_vsync = VSYNC_GPIO_NUM,
    .pin_href = HREF_GPIO_NUM,
    .pin_pclk = PCLK_GPIO_NUM,
    
    .xclk_freq_hz = 20000000,
    .ledc_timer = LEDC_TIMER_0,
    .ledc_channel = LEDC_CHANNEL_0,
    
    .pixel_format = PIXFORMAT_JPEG,
    .frame_size = FRAMESIZE_VGA,
    .jpeg_quality = 12,
    .fb_count = 1,
};

esp_err_t camera_init() {
    //initialize the camera
    esp_err_t err = esp_camera_init(&camera_config);
    if (err != ESP_OK) {
        Serial.println("Camera Init Failed!");
        return err;
    }
    sensor_t * s = esp_camera_sensor_get();
    //initial sensors are flipped vertically and colors are a bit saturated
    if (s->id.PID == OV2640_PID) {
    //        s->set_vflip(s, 1);//flip it back
    //        s->set_brightness(s, 1);//up the blightness just a bit
    //        s->set_contrast(s, 1);
    }
    Serial.println("Camera Init OK!");
    return ESP_OK;
}

void wifi_init(void)
{
    delay(10);
    WiFi.mode(WIFI_STA);
    WiFi.setSleep(false); //鍏抽棴STA妯″紡涓媤ifi浼戠湢锛屾彁楂樺搷搴旈�熷害
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println();
    Serial.println("WiFi Connected OK!");
    Serial.print("IP Address:");
    Serial.println(WiFi.localIP());
    Udp.begin(localUdpPort); //启用UDP监听以接收数据
}

void cssp(){
  camera_fb_t * fb = esp_camera_fb_get();
  uint8_t * temp = fb->buf; //这个是为了保存一个地址,在摄像头数据发送完毕后需要返回,否则会出现板子发送一段时间后自动重启,不断重复
  if (!fb)
  {
      Serial.print( "Camera Capture Failed!");
  }
  else
  { 
    Udp.beginPacket(IPAddress(192,168,2,201), 8081);
    Udp.print("FrameBegin");   //视频数据的标志头
    // 将图片数据分段发送
    int leng = fb->len;
    int timess = leng/maxcache;
    int extra = leng%maxcache;
    for(int j = 0;j< timess;j++)
    {
        Udp.write(fb->buf, maxcache); 
        for(int i =0;i< maxcache;i++)
        {
            fb->buf++;
        }
    }
    Udp.write(fb->buf, extra);
    Udp.println();  
    Udp.print("FrameOverr");    //视频数据的标志尾
    Udp.endPacket();    
    // Serial.print("This Frame Length:");
    // Serial.print(fb->len);
    // Serial.println(".Succes To Send Image For UDP");
    //return the frame buffer back to the driver for reuse
    fb->buf = temp; //将当时保存的指针重新返还
    esp_camera_fb_return(fb);  //这一步在发送完毕后要执行,具体作用还未可知。
  }
  delay(10); //不加延时会导致数据发送混乱 稍微延时增加数据传输可靠性
}
void recv_data(){
  int packetSize = Udp.parsePacket(); //获取当前队首数据包长度
  if (packetSize)                     //如果有数据可用
  {
    char buf[packetSize];
    Udp.read(buf, packetSize); //读取当前包数据
    // Serial.println();
    // Serial.print("Received: ");
    // Serial.println(buf);
    // Serial.print("From IP: ");
    // Serial.println(Udp.remoteIP());
    // Serial.print("From Port: ");
    // Serial.println(Udp.remotePort());
    String tmp = String(buf);
    if(tmp.substring(0,cam_on.length()) == "camon"){
      is_tran_camera = true;
      Udp.beginPacket(IPAddress(192,168,2,201), 8081);
      Udp.print("Camera ON");
      Udp.endPacket();  
    }
    if(tmp.substring(0,cam_off.length()) == "camoff"){
      is_tran_camera = false;
      Udp.beginPacket(IPAddress(192,168,2,201), 8081);
      Udp.print("Camera OFF");
      Udp.endPacket();  
    }
  }
}
void setup() {
  Serial.begin(115200);
  camera_init(); 
  wifi_init(); 
  Serial.println("Sys Is Running!");
}

void loop() 
{
  recv_data();
  if(is_tran_camera){
    cssp();
  }
}

猜你喜欢

转载自blog.csdn.net/weixin_42854045/article/details/128022341