- 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); }
- 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
文章来源:https://www.toymoban.com/news/detail-410650.html
到了这里,关于ESP32 CAM与服务器(python)UDP视频传输的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!