目录
[2、接线表(ESP32-CAM 常用引脚)](#2、接线表(ESP32-CAM 常用引脚))
[1、ESP32-CAM 与 OV2640](#1、ESP32-CAM 与 OV2640)
2、视频流原理(multipart/x-mixed-replace)
[3、HC-SR501 触发抓拍](#3、HC-SR501 触发抓拍)
[1、Web 接口](#1、Web 接口)
[十一、软件设计(.h / .c 多文件工程)](#十一、软件设计(.h / .c 多文件工程))
[2、config.h ------ 全局配置](#2、config.h —— 全局配置)
[3、camera.h / camera.c ------ 摄像头模块](#3、camera.h / camera.c —— 摄像头模块)
[4、storage.h / storage.c ------ SD 卡模块](#4、storage.h / storage.c —— SD 卡模块)
[5、motion.h / motion.c ------ 人体触发模块](#5、motion.h / motion.c —— 人体触发模块)
[6、webserver.h / webserver.c ------ Web 服务模块](#6、webserver.h / webserver.c —— Web 服务模块)
[7、web_page.h ------ 网页内容](#7、web_page.h —— 网页内容)
[8、main.c ------ 主程序](#8、main.c —— 主程序)
[十五、开题报告 & 答辩要点](#十五、开题报告 & 答辩要点)
难度定位 :★★★★☆(偏难硬件型)|适合:想做一个「有画面、演示效果炸裂」选题、愿意折腾摄像头调试的同学|预估周期:4~5 周
一、这个毕设是干什么的?
一句话:做一套用 ESP32-CAM 采集画面、手机或浏览器随时看实时视频、有人活动自动抓拍存证的智能家居视频监控系统。
再展开说:你在家里装一个 ESP32-CAM 小板子,它带 OV2640 摄像头,通电连上 WiFi 后对外提供一个网页地址。你人在外面用手机浏览器打开这个地址,就能看到家里的实时视频画面;再配上人体红外传感器,一旦检测到有人活动,系统会自动抓拍一张照片存进 SD 卡(或上传云端),并推送提醒你「家里有动静」。整套系统的成本不到一百块,比买成品摄像头更有技术含量,答辩演示效果也很直观。
二、它解决什么问题?
成品摄像头贵、还不开放 → 用 ESP32-CAM 自己搭,成本低、代码可改、数据在自己手里;
外出时想看看家里情况 → 手机浏览器打开网页即可看实时视频,随时随地;
整天录像占用空间大 → 只在有人活动时抓拍存证,省空间又抓重点;
普通摄像头没法做二次开发 → 本项目完全开源可控,可加人脸检测、云端上传、远程云台等扩展;
断电/断网后不知道发生了什么 → 抓拍图片存 SD 卡,本地留证不丢。
本质是:把「买个成品摄像头」变成「自己搭一个可看、可拍、可扩展的嵌入式视频监控系统」,这正是物联网毕设里最能体现「软硬件综合能力」的选题之一。
三、核心功能?
| 功能 | 说明 |
|---|---|
| 实时视频流 | ESP32-CAM 提供 HTTP 视频流,浏览器/手机可直接看 |
| 网页控制台 | 网页上查看画面、触发抓拍、查看状态 |
| 人体感应抓拍 | PIR 检测到人活动自动抓拍照片 |
| SD 卡存储 | 抓拍图片按时间命名存入 SD 卡 |
| 手动抓拍 | 网页点按钮随时抓拍单张照片 |
| 定时抓拍 | 可按间隔自动抓拍(如每 5 分钟一张) |
| 画面参数调节 | 亮度、对比度、分辨率可在网页调 |
| 状态显示 | OLED/串口显示 IP、WiFi 状态(可选) |
四、用到哪些技术?
| 类别 | 具体 | 作用 |
|---|---|---|
| 主控+摄像头 | ESP32-CAM(内置 OV2640 摄像头) | 采集图像、运行 Web 服务 |
| 图像传感器 | OV2640(200 万像素) | 输出 JPEG 图像 |
| 通信 | ESP32 内置 WiFi | 提供 HTTP 服务、传输视频流 |
| 视频流协议 | HTTP multipart/x-mixed-replace | 浏览器可连续播放的推流方式 |
| 人体检测 | HC-SR501 人体红外 | 触发自动抓拍 |
| 存储 | Micro SD 卡(SPI 接法) | 保存抓拍图片 |
| Web 框架 | ESP32 WebServer 库 |
处理网页请求、图片接口 |
| 开发 | Arduino IDE + C 语言 | 编写烧录程序 |
提醒 :ESP32-CAM 没有板载 USB 接口,必须用 USB-TTL 串口模块烧录,且烧录时要把 GPIO0 接地进入下载模式,烧完拔掉再上电运行------这是新手最容易卡住的一步。
五、系统是怎么工作的?
ESP32-CAM 上电
↓ 连 WiFi,获得 IP
内置 Web 服务器启动
├── GET / → 网页控制台(看画面、点抓拍)
├── GET /stream → 实时视频流(multipart 推流)
└── GET /capture → 抓拍单张 JPEG
↓
HC-SR501 检测到人
↓ 触发
自动抓拍 → 存 SD 卡(文件名带时间)
↓
(可选)推送提醒 / 上传云端
一句话串起来:上电连 WiFi → 起 Web 服务 → 浏览器看流/抓拍 → PIR 触发自动抓拍存卡。
这套「摄像头 + Web 服务 + 触发抓拍」的架构,是所有嵌入式视频监控类毕设的通用骨架,也可扩展成门铃摄像头、仓库监控、农业看护。
六、大概怎么做?
买齐硬件(ESP32-CAM + USB-TTL + SD 卡 + PIR + 电源);
先把摄像头调通:烧最简例程,串口能看到 IP,浏览器打开能看到画面(这一步最关键);
起 Web 服务:一个页面 + 一个
/stream视频流接口 + 一个/capture抓拍接口;接 SD 卡:能读卡、能写一张测试图片;
接 PIR:检测到人触发抓拍并保存;
网页加控制:手动抓拍按钮、分辨率下拉、画面参数调节;
联调:手机浏览器远程看流、走动触发抓拍、SD 卡能看到带时间戳的图片,链路跑通即完成。
核心难点是「ESP32-CAM 烧录接线 + 摄像头初始化参数 + 视频流接口」,调通这三样后面就顺了。下面逐步展开。
七、硬件清单与接线
1、硬件清单
| 器件 | 型号/规格 | 数量 |
|---|---|---|
| 主控摄像头 | ESP32-CAM(AI-Thinker,带 OV2640) | 1 |
| 烧录工具 | USB-TTL(CH340/CP2102) | 1 |
| 存储卡 | Micro SD 卡(≤32G,FAT32) | 1 |
| 人体红外 | HC-SR501 | 1 |
| 电源 | 5V 2A(USB-TTL 供电可能不够,建议独立供电) | 1 |
| 下载按键 | 杜邦线短接 GPIO0 到 GND(或用底板按键) | 1 |
2、接线表(ESP32-CAM 常用引脚)
| 功能 | ESP32-CAM 引脚 | 说明 |
|---|---|---|
| 摄像头数据 | GPIO0/5/18/19/21/22/23/25/26/27 | 内部固定,板载已连接,不用外接 |
| 摄像头 XCLK | GPIO0 | 板载连接 |
| PIR 输入 | GPIO13 | 人体红外 OUT(注意避开摄像头占用脚) |
| SD 卡 CMD | GPIO15 | SPI 模式 |
| SD 卡 CLK | GPIO14 | SPI 模式 |
| SD 卡 DATA | GPIO2 | SPI 模式 |
| SD 卡 CD | GPIO4 | 板载 SD 座常接 |
| 烧录 TX | U0TXD(GPIO1) | 接 USB-TTL RX |
| 烧录 RX | U0RXD(GPIO3) | 接 USB-TTL TX |
| 烧录 GND | GND | 与 USB-TTL 共地 |
| 烧录 5V | 5V | USB-TTL 5V 供(或独立供电) |
| 下载模式 | GPIO0 → GND | 烧录时必须接地,烧完断开 |
关键提醒 :ESP32-CAM 引脚被摄像头和 SD 卡占了大部分,可用的 IO 非常少(GPIO12/13/14/15/2/4 常被占用),接 PIR 前一定要查清楚哪个脚是真空闲的(GPIO13 相对安全);供电一定要足,USB-TTL 供电不足会导致摄像头初始化失败、串口反复重启。
八、核心器件原理简述
1、ESP32-CAM 与 OV2640
ESP32-CAM 是一块把 ESP32-S + OV2640 摄像头 + SD 卡座 + 闪光灯集成在一起的小板;
OV2640 是 200 万像素 CMOS 图像传感器,输出 JPEG 压缩图像,直接给 ESP32 处理,省内存;
只有 4MB PSRAM 版本才够跑高分辨率视频流,买的时候一定选带 PSRAM 的;
摄像头通过 8 位并口 + I2C(SCCB)配置,用
esp_camera.h的esp_camera_init一次初始化。
2、视频流原理(multipart/x-mixed-replace)
传统视频要 RTSP/WebRTC,ESP32 跑不动;HTTP 的 multipart/x-mixed-replace 是最轻量的方案;
服务端持续发送「边界 + 一帧 JPEG + 边界 + 下一帧」,浏览器收到就顺序显示,形成连续画面;
ESP32 官方例程
CameraWebServer就是这个原理,帧率一般 5~15 fps,够监控用。
3、HC-SR501 触发抓拍
热释电检测人体红外变化,输出高电平;
程序里检测到上升沿 → 调
esp_camera_fb_get()取一帧 → 存 SD 卡;加冷却时间避免连续触发刷满卡。
九、接口与抓拍设计
1、Web 接口
| 路径 | 方法 | 功能 |
|---|---|---|
/ |
GET | 网页控制台 |
/stream |
GET | 实时视频流 |
/capture |
GET | 抓拍单张 JPEG |
/save |
GET | 抓拍并存 SD 卡 |
/status |
GET | 返回 JSON 状态(IP、分辨率、卡片状态) |
2、抓拍文件命名
/20261109_143012.jpg
格式:YYYYMMDD_HHMMSS.jpg,按时间排序一目了然。
3、触发策略
PIR 触发 → 抓拍 1 张存卡 → 冷却 10 秒;
网页手动点「抓拍」→ 抓拍 1 张并存卡;
定时抓拍可选(每 5 分钟一张,用于长时间留痕)。
十、开发环境搭建
安装 Arduino IDE(2.x);
添加 ESP32 板卡(开发板管理器搜索
esp32安装),开发板选 AI Thinker ESP32-CAM;配置:
Partition Scheme选Huge APP (3MB No OTA/1MB SPIFFS),PSRAM选Enabled;安装库:
ESP32自带esp_camera、WiFi、WebServer,SD 用SD_MMC或SD;烧录:GPIO0 接 GND → 点上传 → 显示
Connecting...时按一下 RST → 烧完断开 GPIO0 → 按 RST 运行;串口监视器 115200 看 IP 地址。
十一、软件设计(.h / .c 多文件工程)
代码按功能拆分:头文件(.h)只放宏、结构体、函数声明,源文件(.c)放具体实现,职责清晰、符合正式工程规范。
1、工程文件结构
esp32cam_monitor/
├── config.h // 全局配置:WiFi、引脚、分辨率
├── camera.h // 摄像头模块声明
├── camera.c // 摄像头初始化与抓拍实现
├── storage.h // SD 卡模块声明
├── storage.c // 存卡实现
├── motion.h // PIR 触发模块声明
├── motion.c // 人体检测与冷却实现
├── webserver.h // Web 服务模块声明
├── webserver.c // 网页/视频流/抓拍接口实现
├── web_page.h // 网页 HTML 内容(独立存放)
└── main.c // 主程序:setup() / loop()
2、config.h ------ 全局配置
#ifndef CONFIG_H
#define CONFIG_H
/* WiFi(换成自己的) */
#define WIFI_SSID "your_wifi"
#define WIFI_PASS "your_pass"
/* PIR */
#define PIN_PIR 13
/* 抓拍冷却时间(毫秒),避免连续刷卡 */
#define CAPTURE_COOLDOWN_MS 10000
/* 默认分辨率(需与 PSRAM 匹配,VGA 稳定,UXGA 建议 4MB PSRAM) */
#define FRAME_SIZE FRAMESIZE_VGA /* 640x480 */
#endif
3、camera.h / camera.c ------ 摄像头模块
camera.h(声明):
#ifndef CAMERA_H
#define CAMERA_H
#include <stdbool.h>
#include "esp_camera.h"
bool camera_init(void);
bool camera_capture_jpeg(uint8_t **buf, size_t *len); /* 取一帧 */
void camera_release(uint8_t *buf); /* 释放帧缓冲 */
#endif
camera.c(实现,AI-Thinker 引脚固定):
#include "camera.h"
#include "config.h"
/* AI-Thinker ESP32-CAM 固定引脚定义,不能随意改 */
static camera_config_t cfg = {
.pin_pwdn = 32, .pin_reset = -1,
.pin_xclk = 0, .pin_sscb_sda = 26, .pin_sscb_scl = 27,
.pin_d7 = 35, .pin_d6 = 34, .pin_d5 = 39, .pin_d4 = 36,
.pin_d3 = 21, .pin_d2 = 19, .pin_d1 = 18, .pin_d0 = 5,
.pin_vsync = 25, .pin_href = 23, .pin_pclk = 22,
.xclk_freq_hz = 20000000,
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,
.pixel_format = PIXFORMAT_JPEG,
.frame_size = FRAME_SIZE,
.jpeg_quality = 12,
.fb_count = 2, /* 双缓冲,视频流更流畅 */
.fb_location = CAMERA_FB_IN_PSRAM,
.grab_mode = CAMERA_GRAB_WHEN_EMPTY,
};
bool camera_init(void) {
esp_err_t err = esp_camera_init(&cfg);
return (err == ESP_OK);
}
bool camera_capture_jpeg(uint8_t **buf, size_t *len) {
camera_fb_t *fb = esp_camera_fb_get();
if (!fb) return false;
*buf = fb->buf;
*len = fb->len;
return true;
}
/* 用完必须释放,否则内存泄漏、很快卡死 */
void camera_release(uint8_t *buf) {
camera_fb_t *fb = esp_camera_fb_get(); /* 占位说明:实际用 fb 指针释放 */
(void)fb; (void)buf;
}
说明:
esp_camera_fb_return()需要原始camera_fb_t*指针,工程里建议camera_capture_jpeg直接返回camera_fb_t*,调用方用完调esp_camera_fb_return()。下面storage.c用这种写法。
4、storage.h / storage.c ------ SD 卡模块
storage.h(声明):
#ifndef STORAGE_H
#define STORAGE_H
#include <stdbool.h>
#include <stddef.h>
bool storage_init(void);
bool storage_save_jpeg(const uint8_t *data, size_t len); /* 按时间命名存图 */
#endif
storage.c(实现):
#include "storage.h"
#include "config.h"
#include <FS.h>
#include <SD_MMC.h>
#include <time.h>
bool storage_init(void) {
/* ESP32-CAM 一般用 SD_MMC 1-bit 模式接卡 */
if (!SD_MMC.begin("/sdcard", true)) return false;
return (SD_MMC.cardType() != CARD_NONE);
}
bool storage_save_jpeg(const uint8_t *data, size_t len) {
char path[32];
time_t now = time(nullptr);
struct tm *t = localtime(&now);
snprintf(path, sizeof(path), "/%04d%02d%02d_%02d%02d%02d.jpg",
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
File f = SD_MMC.open(path, FILE_WRITE);
if (!f) return false;
size_t n = f.write(data, len);
f.close();
return (n == len);
}
5、motion.h / motion.c ------ 人体触发模块
motion.h(声明):
#ifndef MOTION_H
#define MOTION_H
#include <stdbool.h>
void motion_init(void);
bool motion_triggered(void); /* 是否触发(含冷却判断) */
#endif
motion.c(实现,带冷却):
#include "motion.h"
#include "config.h"
static uint32_t lastMs = 0;
void motion_init(void) { pinMode(PIN_PIR, INPUT); }
bool motion_triggered(void) {
if (digitalRead(PIN_PIR) != HIGH) return false;
if (millis() - lastMs < CAPTURE_COOLDOWN_MS) return false;
lastMs = millis();
return true;
}
6、webserver.h / webserver.c ------ Web 服务模块
webserver.h(声明):
#ifndef WEBSERVER_H
#define WEBSERVER_H
void webserver_init(void);
void webserver_handle(void); /* 在 loop 中调用 */
#endif
webserver.c(实现,含视频流与抓拍):
#include "webserver.h"
#include "config.h"
#include "camera.h"
#include "storage.h"
#include "web_page.h"
#include <WiFi.h>
#include <WebServer.h>
static WebServer server(80);
static uint32_t frameCnt = 0;
/* GET / ------ 返回控制台网页 */
static void handle_index(void) {
server.send_P(200, "text/html", PAGE_HTML);
}
/* GET /stream ------ 持续推流(multipart/x-mixed-replace) */
static void handle_stream(void) {
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
server.send(200, "multipart/x-mixed-replace; boundary=frame");
while (true) {
camera_fb_t *fb = esp_camera_fb_get();
if (!fb) break;
/* 一帧:边界 + JPEG 头 + 数据 + 边界 */
server.sendContent("--frame\r\nContent-Type: image/jpeg\r\n\r\n");
server.sendContent((const char *)fb->buf, fb->len);
server.sendContent("\r\n");
esp_camera_fb_return(fb);
frameCnt++;
if (frameCnt > 100000) break; /* 防止长时间占用 */
delay(50);
}
}
/* GET /save ------ 抓拍并存 SD 卡 */
static void handle_save(void) {
camera_fb_t *fb = esp_camera_fb_get();
if (!fb) { server.send(500, "text/plain", "capture failed"); return; }
bool ok = storage_save_jpeg(fb->buf, fb->len);
esp_camera_fb_return(fb);
server.send(200, "text/plain", ok ? "saved" : "save failed");
}
/* GET /status ------ 返回状态 */
static void handle_status(void) {
String s = "{\"ip\":\"" + WiFi.localIP().toString()
+ "\",\"frames\":" + String(frameCnt) + "}";
server.send(200, "application/json", s);
}
void webserver_init(void) {
server.on("/", handle_index);
server.on("/stream", handle_stream);
server.on("/save", handle_save);
server.on("/status", handle_status);
server.begin();
}
void webserver_handle(void) {
server.handleClient();
}
7、web_page.h ------ 网页内容
#ifndef WEB_PAGE_H
#define WEB_PAGE_H
static const char PAGE_HTML[] PROGMEM = R"HTML(
<html><head><meta charset="utf-8">
<title>ESP32-CAM 视频监控</title></head>
<body style="background:#0a1428;color:#8ef;font-family:sans-serif;text-align:center">
<h2>智能家居视频监控</h2>
<img src="/stream" style="width:640px;border:2px solid #2af;border-radius:8px">
<p><button onclick="location.href='/save'">抓拍存卡</button>
<button onclick="location.href='/status'">查看状态</button></p>
</body></html>
)HTML";
#endif
8、main.c ------ 主程序
#include "config.h"
#include "camera.h"
#include "storage.h"
#include "motion.h"
#include "webserver.h"
#include <WiFi.h>
void setup() {
Serial.begin(115200);
/* ① 摄像头初始化,失败就没法往下走 */
if (!camera_init()) {
Serial.println("camera init failed");
return;
}
/* ② SD 卡初始化(失败不致命,只是不能存卡) */
Serial.println(storage_init() ? "SD ok" : "SD fail");
/* ③ 连 WiFi */
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
Serial.print("IP: "); Serial.println(WiFi.localIP());
/* ④ 起 Web 服务 */
motion_init();
webserver_init();
}
void loop() {
/* ① 处理网页请求(视频流也在这里) */
webserver_handle();
/* ② PIR 触发 → 抓拍存卡 */
if (motion_triggered()) {
camera_fb_t *fb = esp_camera_fb_get();
if (fb) {
bool ok = storage_save_jpeg(fb->buf, fb->len);
Serial.println(ok ? "motion: saved" : "motion: save fail");
esp_camera_fb_return(fb);
}
}
delay(10);
}
以上为核心模块代码。需要时可继续扩展:新增
upload.c(抓拍上传云端/图床)、face.c(人脸检测)、servo.c(二轴云台转向)、timer.c(定时抓拍),主程序只调用接口,逻辑一目了然。
十二、代码要点讲解
.h/.c分离 :.h只放宏、结构体、函数声明,.c放实现隐藏细节,模块独立便于扩展,是论文「模块化设计」的要点;
config.h集中配置:WiFi、引脚、分辨率、冷却时间都收在一个文件,改参数不用翻代码;摄像头引脚不能改 :AI-Thinker 板的 OV2640 引脚是焊死的,
camera_config_t必须照官方给;
fb_count = 2双缓冲:视频流更流畅,单缓冲容易撕裂或掉帧;
esp_camera_fb_return必须调用:帧缓冲在 PSRAM,不释放几百帧就耗尽内存卡死;multipart 推流:不用 RTSP,浏览器直接显示,最轻量方案;
抓拍冷却
CAPTURE_COOLDOWN_MS:PIR 会连续输出高电平,加冷却避免一秒钟存几十张;文件按时间命名 :
YYYYMMDD_HHMMSS.jpg,后期按时间找图非常方便。
十三、功能测试与验收
| 功能 | 实现方式 | 测试方法 |
|---|---|---|
| 摄像头初始化 | camera_init |
串口无报错,继续往下走 |
| WiFi 连接 | WiFi.begin |
串口打印 IP 地址 |
| 网页控制台 | handle_index |
浏览器打开 IP 能看到页面 |
| 实时视频流 | handle_stream |
页面上画面连续刷新 |
| 手动抓拍 | handle_save + 网页按钮 |
点按钮,SD 卡出现新图片 |
| 人体触发抓拍 | motion_triggered |
手在 PIR 前晃,SD 卡新增图片 |
| 状态查询 | /status |
返回 IP 与帧数 JSON |
| 远程访问 | 同一局域网 | 手机连同一 WiFi 打开 IP 能看画面 |
分步验收清单:
烧录后串口打印 IP → 摄像头与 WiFi OK;
浏览器打开 IP 看到网页 → Web 服务 OK;
页面上画面连续动 → 视频流 OK;
点「抓拍存卡」后 SD 卡出现 jpg → 抓拍存卡 OK;
手在 PIR 前晃动,SD 卡自动新增带时间戳图片 → 触发抓拍 OK;
手机同 WiFi 打开 IP 能看画面 → 远程监控 OK。
十四、能给你什么启发?
1. 选题优势:有画面、演示效果直观,答辩时能当场用手机看实时视频,冲击力强;软硬件结合紧密,能体现摄像头驱动、网络编程、文件系统多方面能力;成本低(不到百元),扩展空间大,容易做出彩。
2. 想冲更高分数,随便往这几个方向扩:
加人脸检测:ESP32-CAM 自带人脸识别例程,可以做「陌生人抓拍」;
加二轴云台:两个舵机让摄像头上下左右转,远程控制视角;
加上传云端:抓拍图片上传图床/服务器,不怕丢卡;
加门铃功能:按键触发抓拍+推送+语音提示,做成智能门铃;
加夜间补光:板载闪光灯或红外补光,夜里也能拍;
加多设备组网:多个 ESP32-CAM 覆盖不同房间,一个页面聚合查看。
十五、开题报告 & 答辩要点
1、开题报告可直接改用的表述
1. 选题依据(背景):家庭安防与远程看护需求日益增长,市售摄像头多为封闭产品、价格较高且难以二次开发。ESP32-CAM 将 WiFi 主控与图像传感器集成于一体,成本低、可编程,为构建自主可控的家庭视频监控系统提供了条件。
2. 研究意义:本课题将图像采集、嵌入式 Web 服务、无线通信与文件系统技术相结合,一方面实现家庭场景的实时远程视频查看与移动侦测抓拍,提升居家安全感知能力;另一方面完整覆盖摄像头驱动、HTTP 服务、视频流协议、SD 卡存储等物联网关键技术,对巩固专业知识、锻炼软硬件综合开发能力有重要意义。
3. 系统功能概述:系统以 ESP32-CAM 为主控,通过 OV2640 采集图像,连入 WiFi 后启动内置 Web 服务器,用户可用手机或浏览器访问网页查看实时视频流、手动抓拍;配合 HC-SR501 人体红外传感器,检测到人活动时自动抓拍并将图片按时间命名存入 SD 卡,实现移动侦测与本地留证。
4. 创新点(按实际情况选取):
采用 HTTP multipart 视频流方案,在低成本模组上实现浏览器直连实时预览;
实现移动侦测触发抓拍,只在有人活动时留证,节省存储;
系统完全自主可控、代码开源,具备人脸检测、云台等扩展空间。
5. 技术难点:
ESP32-CAM 的烧录接线与摄像头初始化参数配置;
视频流接口实现与帧缓冲内存管理;
SD 卡文件系统写入与并发访问协调。
2、答辩常见问题(参考回答要点)
| 可能被问 | 回答要点 |
|---|---|
| 视频流是怎么实现的? | HTTP multipart/x-mixed-replace 持续推送 JPEG 帧,浏览器顺序显示成视频 |
| 为什么不用 RTSP? | ESP32 算力内存有限,multipart 最轻量,浏览器原生支持 |
| 帧率多少? | VGA 下约 10~15 fps,够监控;UXGA 会明显下降 |
| 抓拍怎么触发? | PIR 检测到人上升沿触发,加 10 秒冷却避免刷卡 |
| 图片存哪? | SD 卡,按 YYYYMMDD_HHMMSS 命名,按时间好找 |
| 为什么必须选带 PSRAM 的? | 高分辨率图像缓冲需要 PSRAM,否则内存不够会初始化失败 |
| 手机在外面能看吗? | 同一局域网可直接看;外网需内网穿透或云端中转 |
| 系统有哪些改进空间? | 人脸检测、云台、云端上传、夜间补光、多机聚合等 |