ESP32 CAM与服务器(python)UDP视频传输

这篇具有很好参考价值的文章主要介绍了ESP32 CAM与服务器(python)UDP视频传输。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  1. ESP32 CAM Arduino代码
    #include "esp_camera.h"
    #include <WiFi.h>
    #include "AsyncUDP.h"
    #include <vector>
    
    const char *ssid = "dsx_zj";
    const char *password = "dsxbs725";
    
    #define maxcache 1430
    
    //设置每次发送最大的数据量,如果选择一次发送会出现丢失数据,经测试,我这边每
    //次最大发送1436,选择一个稍微小点的数
    AsyncUDP udp;                      //异步udp既可以发送也可以接收
    
    #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());
    }
    
    
    void setup() {
        Serial.begin(115200);
        camera_init(); //
        wifi_init(); //
        Serial.println("Sys Is Running!");
        //此部分可忽略
        if(udp.connect(IPAddress(192,168,0,2), 8080)) 
        {
            Serial.println("UDP Server Connected!");
            udp.onPacket([](AsyncUDPPacket packet) {
                Serial.print("UDP Packet Type: ");
                Serial.print(packet.isBroadcast()?"Broadcast":packet.isMulticast()?"Multicast":"Unicast");
                Serial.print(", From: ");
                Serial.print(packet.remoteIP());
                Serial.print(":");
                Serial.print(packet.remotePort());
                Serial.print(", To: ");
                Serial.print(packet.localIP());
                Serial.print(":");
                Serial.print(packet.localPort());
                Serial.print(", Length: ");
                Serial.print(packet.length());
                Serial.print(", Data: ");
                Serial.write(packet.data(), packet.length());
                Serial.println();
                //reply to the client
                packet.printf("Got %u bytes of data", packet.length());
            });
            //Send unicast
            //udp.print("Hello Server!");
        }
        //忽略到此部分
    }
    
    void loop() 
    {
        if(udp.connect(IPAddress(192,168,0,2), 8080))  //连接远端的udp
        {
          while(true){
            //acquire a frame
            camera_fb_t * fb = esp_camera_fb_get();
            uint8_t * temp = fb->buf; //这个是为了保存一个地址,在摄像头数据发送完毕后需要返回,否则会出现板子发送一段时间后自动重启,不断重复
            if (!fb)
            {
                Serial.print( "Camera Capture Failed!");
            }
            else
            { 
              // 将图片数据分段发送
              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("Frame Over");     
              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(60000);
            delay(20); //不加延时会导致数据发送混乱 稍微延时增加数据传输可靠性
          }
        }else{
          Serial.println("Connected UDP Server Fail,After 10 Seconds Try Again!");
        }
        delay(10000);
    }
    
    
  2. UDP Server代码
    import socket
    import numpy as np
    import cv2
    import time
    
    # 创建UDP服务器
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 注意 这里是服务器的IP和端口  不是客户端的
    addr = ('192.168.0.2', 8080)
    # 在云服务器上开启服务要使用内网的IP  腾讯云的地址
    # addr = ('10.0.4.11', 8001)
    s.bind(addr)
    end_data = b'Frame Over'
    temp_data = b''
    #ESP32 Cam 返回数据格式
    #b'(\xa0\x04\xa2\x98\x05%\x16\x00\xa4'  这个以及上面的都是图片数据
    # b'\r\n'  返回的分隔符和回车 回车是自己写的代码(udp.println();  )  \r\n 长度为2  测试加在图片数据不影响显示
    # b'Frame Over' 返回的结束符  用于判断是否一张图片结束  udp.print("Frame Over");
    # UDP会发送单独的一个包   但是TCP不会单独发送 会和其他混在一起 这边TCP和UDP处理方式不一样
    millis1 = int(round(time.time() * 1000))
    while True:
        data, addr= s.recvfrom(1430)
        if data == end_data: # 判断这一帧数据是不是结束语句 UDP会发送单独的一个包   但是TCP不会单独发送
            # print(temp_data) temp_data数据多了 b'\r\n' 但是不影响图片的显示
            # 显示图片
            receive_data = np.frombuffer(temp_data, dtype='uint8')  # 将获取到的字符流数据转换成1维数组
            r_img = cv2.imdecode(receive_data, cv2.IMREAD_COLOR)  # 将数组解码成图像
            r_img = r_img.reshape(480, 640, 3)
            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('server_frame', r_img)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
            print("接收到的数据包:" + str(len(temp_data)))  # 显示该张照片数据大小
            temp_data = b''  # 清空数据 便于下一章照片使用
            millis1 = millis2
        else:
            temp_data = temp_data + data  # 不是结束的包 讲数据添加进temp_data

文章来源地址https://www.toymoban.com/news/detail-410650.html

到了这里,关于ESP32 CAM与服务器(python)UDP视频传输的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 安卓App与ESP32Cam的视频传输

    实现结果 app可以控制Esp32Cam的摄像头开关和闪光灯的开关 Esp32Cam代码   安卓app代码    

    2023年04月08日
    浏览(38)
  • ESP32网络开发实例-TCP服务器数据传输

    本文将详细介绍在Arduino开发环境中,实现一个ESP32 TCP服务器,从而达到与TCP客户端数据交换的目标。 Internet 协议(IP)是 Internet 的地址系统,具有将数据包从源设备传递到目标设备的核心功能。IP 是建立网络连接的主要方式,奠定了 Internet 的基础。IP 不负责数据包排序或错

    2024年02月07日
    浏览(58)
  • Opencv保存ESP32-CAM视频流

    Opencv保存ESP32-CAM视频流 esp32cam是一个很便宜的视频模组,可以用作监控等功能。此时就需要保存esp32的视频流,方便查看等操作,python代码如下 前置条件:视频流正常,已安装opencv

    2024年02月08日
    浏览(67)
  • QT获取ESP32-CAM视频流分析

    1、前言       使用QT获取ESP32-CAM视频流的原理是在QT模拟浏览器发送http请求,然后ESP32-CAM返回视频流,当QT界面接收到数据后,对数据进行解析,然后合成图片进行显示。       在QT中发送http请求的方法很多,这里使用Qt网络模块中的类QNetworkReply发送http请求。 2、核心代

    2023年04月20日
    浏览(38)
  • 【NodeMCU-ESP8266】Arduino环境下建立UDP服务器及WiFiUDP库常用函数详解

    目录 一、UDP协议概述         1、UDP基本概念         2、UDP的主要特点         3、UDP的基本报文格式 ​二、ESP8266官方UDP库相关函数详解 三、建立UDP服务器的一般流程 四、ESP8266官方库 UDP 示例程序演示 五、ESP8266官方库 UDP 程序运行说明         1、将程序编译并

    2024年04月24日
    浏览(44)
  • esp32 cam不使用官方示例完成视频内网穿透

    刚才给大家讲解了esp32cam使用arduino ide官方示例内网穿透的方法,因目前免费的内网穿透软件无法完成公网ip的两个端口映射,因此作者去学习了另一个不使用官方示例也可以内网穿穿透的方法。 在此先介绍b站王铭东老师,我是在这位老师的基础上学习的,还有csdn上的这位老

    2024年04月14日
    浏览(33)
  • QT+ESP32-CAM上位机获取视频流(附源码)

    第二章 qt获取esp32-cam视频流 本文是基于esp32-cam 官方示例扩展的QT上位机程序 可以获取视频流来做一些图像处理 帧率和直接用网页打开的帧率差不多(25FPS) 由于也是刚玩ESP32-cam 在网上想找个QT上位机的程序来做一些测试 但是找到的一些例程获取的帧率比较低所以开发了一个测

    2024年02月03日
    浏览(44)
  • ESP32网络开发实例-搭建ESP32固件远程升级服务器

    我们在前面的文章中,已经实现了OTA方式升级固件的两种方式:在Arduino IDE 中升级和Web浏览器中升级。这两种方式都不能满足设备自动升级的需求。在本文中,将详细介绍如何搭建一个ESP32固件远程升级服务器。通过远程升级服务器,ESP32设备可以根据固件版本号进行自动升级

    2024年01月23日
    浏览(53)
  • Arduino IDE + Esp32 Cam + 实现视频流 + 开发环境部署

    1、开发环境 Arduino ide 版本:2.2.1 esp32工具:2.0.5 示例代码

    2024年02月08日
    浏览(72)
  • ESP32构建简单WebServer服务器

    WebServer 服务器 此案例中,我们将创建一个最简单的 webserver 服务器 案例实现:ESP32 通过 SPIFFS 上传网页文件并保存,之后手机开启热点,ESP32 连接到该热点;与手机处于同一热点下的任何一个设备(下面用电脑演示)都可以通过 ESP32 反馈的内网地址访问其构建的网页! ESP

    2024年02月11日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包