b8hqQHaWdEN1 发表于 2025-5-5 01:38:30

“ESP32-S3 AI摄像头”边缘轮廓检测—AI数万物

本帖最后由 b8hqQHaWdEN1 于 2025-5-5 01:55 编辑

【概述】
“ESP32-S3 AI摄像头”模块是一款基于ESP32-S3的开发板,搭载了一个OV3660摄像头,集成了边缘AI处理能力的多功能开发平台,具备强大的神经网络计算能力,本项目就以该摄像头为核心,展示一下该摄像头强大的图像采集和边缘轮廓检测能力。
【项目来源】
本项目的灵感来源于路边的烧烤摊,在有一天吃夜宵时,贴主突发奇想,将”ESP32-S3 AI摄像头模块”的边缘轮廓检测用于结账时数签子,这样就可以脱离人工计数的误差,进一步解放双手,实现自动化建设,但是,该项目不仅仅只能用于数签子,还可以用于所有的同类计数识别,也可以进一步优化,实现多个种类同时识别的功能。
【功能点】
本项目分为设备端(“ESP32-S3 AI摄像头”)和客户端(电脑python),原理如下:
1. 设备端:以“ESP32-S3 AI摄像头”为核心,连接网络获取ip地址并建立Web服务器,通过摄像头采集JPEG图像上传到该ip地址服务器。
2. 客户端:通过访问相应URL获取图像数据,将图像数据解码为OpenCV图像格式-灰度图像-边缘检测-绘制轮廓,在窗口显示实时图像和边缘图像。通过按键实现计数的功能。
【未来展望】
目前该项目是通过摄像头采集数据发送至电脑,后续将移植到摄像头本地运行,在功能方面,不仅可以添加集成例如颜色识别的功能,另该项目更加智能化,也可以添加代码变量,统计各项数据,进一步完善该作品。
【功能实现】一.准备工作

设备端(使用Arduino ide开发环境):
1.下载Arduino IDE,下载esp32主板,这部分可以在产品维库中实现,因此不在赘述。
2.配置好该开发板参数,项目-导入库-管理库-下载好“WiFi”“WebServer”两个库文件。

客户端(电脑运行python开发环境):1.打开python代码,下载numpy和opencv-py两个库
2.在你的python开发环境输入
“pip install numpy”
”Pip install opencv-python“
回车并下载,
至此准备工作已全部完成。


二.代码实现

准备工作结束后就可以复制如下代码粘贴到Arduion ide中:
#include <WiFi.h>
#include <WebServer.h>
#include <esp_camera.h>

// ================= 用户配置区域 =================
const char* ssid = "U123";    //替换你的wifi
const char* password = "88888888";//替换你的密码

// 摄像头引脚配置
#define PWDN_GPIO_NUM   -1
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM   5
#define Y9_GPIO_NUM       4
#define Y8_GPIO_NUM       6
#define Y7_GPIO_NUM       7
#define Y6_GPIO_NUM       14
#define Y5_GPIO_NUM       17
#define Y4_GPIO_NUM       21
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM       16
#define VSYNC_GPIO_NUM    1
#define HREF_GPIO_NUM   2
#define PCLK_GPIO_NUM   15
#define SIOD_GPIO_NUM   8
#define SIOC_GPIO_NUM   9

const framesize_t FRAME_SIZE = FRAMESIZE_QVGA;// 320x240
const int JPEG_QUALITY = 15;                  // 质量 (0-63)
const int FB_COUNT = 3;                         // 帧缓冲区数量
// ==============================================

WebServer server(80);

void setupCamera() {
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;

// 自适应配置
if(psramFound()){
    config.frame_size = FRAME_SIZE;
    config.jpeg_quality = JPEG_QUALITY;
    config.fb_count = FB_COUNT;
} else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 15;
    config.fb_count = 1;
}

// 初始化摄像头
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
    Serial.printf("摄像头初始化失败: 0x%x", err);
    ESP.restart();
}

// 图像方向修正
sensor_t *s = esp_camera_sensor_get();
s->set_vflip(s, 1);    // 垂直翻转(0关闭1开启)
s->set_hmirror(s, 1);// 水平镜像(0关闭1开启)
}

void setupWiFi() {
WiFi.begin(ssid, password);
WiFi.setSleep(false);

Serial.print("正在连接WiFi");
while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
}

Serial.println("\nWiFi已连接");
Serial.print("访问地址: http://");
Serial.println(WiFi.localIP());
}

void handleJPG() {
camera_fb_t *fb = esp_camera_fb_get();
if(!fb) {
    server.send(500, "text/plain", "Camera Error");
    return;
}

WiFiClient client = server.client();

// 构建完整HTTP响应
String response = "HTTP/1.1 200 OK\r\n";
response += "Content-Type: image/jpeg\r\n";
response += "Content-Length: " + String(fb->len) + "\r\n";
response += "Connection: close\r\n\r\n";

// 分块发送数据
client.print(response);
client.write(fb->buf, fb->len);

esp_camera_fb_return(fb);
}

void setup() {
Serial.begin(115200);
delay(1000);// 等待串口初始化

setupCamera();
setupWiFi();

// 路由设置
server.on("/", HTTP_GET, [](){
    server.sendHeader("Location", "/jpg");
    server.send(302, "text/plain", "");
});

server.on("/jpg", HTTP_GET, handleJPG);

server.begin();
Serial.println("HTTP服务器已启动");
}

void loop() {
server.handleClient();
delay(2);
}</font>

步骤如下
设备端:
1.在Arduino IDE中选择esp32-s3主板及其串口
2.File->Examples->ESP32->Camera->CameraWebServer示例
3.使用下面的代码替换CameraWebServer中的代码,只要替换主程序即可
(注意:需要填入WIFI账号密码)
4.上传程序,静等连接WiFi,打开串口监视器返回IP地址(注:电脑和主板需在同一局域网中)
5.打开浏览器,在Web地址中粘贴获取的IP地址,刷新就可以查看摄像头获取的图片。



客户端:
import cv2
import urllib.request
import numpy as np

url = 'http://192.168.0.106/jpg'# 获取的esp32-s3 ai的ip地址

# 创建显示窗口
cv2.namedWindow("live transmission", cv2.WINDOW_AUTOSIZE)

while True:
    try:
      # 获取图像数据
      img_resp = urllib.request.urlopen(url)
      imgnp = np.array(bytearray(img_resp.read()), dtype=np.uint8)
      img = cv2.imdecode(imgnp, -1)
      
      # 如果图像为空则跳过后续处理
      if img is None:
            continue
            
      # 图像处理流程
      gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
      blurred = cv2.GaussianBlur(gray, (11, 11), 0)
      canny = cv2.Canny(blurred, 30, 150)
      dilated = cv2.dilate(canny, (1, 1), iterations=2)
      contours, _ = cv2.findContours(dilated.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
      
      # 绘制轮廓
      cv2.drawContours(img, contours, -1, (0, 255, 0), 2)
      
      # 显示结果
      cv2.imshow("Edge Detection", canny)
      cv2.imshow("Live Feed with Contours", img)
      
      # 按键处理
      key = cv2.waitKey(1) & 0xFF
      if key == ord('q'):
            break
      elif key == ord('a'):
            print(f"检测到轮廓数量: {len(contours)}")
            
    except Exception as e:
      print(f"发生错误: {str(e)}")
      break

cv2.destroyAllWindows()</font>

1.打开python开发环境,复制以上代码并粘贴,修改IP为串口监视器获取的IP地址
2.屏幕上显示实时图像和边缘检测图像
3.按下键盘的“Q”键退出程序,按下“A”键检测检测的边缘数量。




https://www.bilibili.com/video/BV1hAVKzQEEn?buvid=XUB283FB9990F888F282764E1B889A1689536&from_spmid=main.space.0.0&is_story_h5=false&mid=B%2B%2Bap2FLB1nam6J37LLtxQ%3D%3D&plat_id=116&share_from=ugc&share_medium=android&share_plat=android&share_session_id=596a16a9-d41f-48bd-8394-40e824734815&share_source=COPY&share_tag=s_i&spmid=united.player-video-detail.0.0×tamp=1746381271&unique_k=wyFrICh&up_id=184951246


页: [1]
查看完整版本: “ESP32-S3 AI摄像头”边缘轮廓检测—AI数万物