今天把 ESP32-CAM 包裝成「真的可交作業的專題」:
① 門口管家(偵測 → 連拍存證 → LINE 通知)
② 寵物自拍相簿(吃飯就拍、補光不翻車)
③ 簡易客流計數(雙區域跨線法)
不用樹莓派、不用雲主機,單一 ESP32-CAM 就能跑(有網路即可 LINE 推播)。
/sdcard/DCIM/
├─ 2025-10-06/
│ ├─ 00-15-00.jpg
│ ├─ event_00-42-12_1.jpg
│ ├─ event_00-42-12_2.jpg
│ └─ event_00-42-12_3.jpg
└─ 2025-10-07/ ...
cleanOld()
,每小時跑一次。[攝影取景] → [畫面變化判斷] → (成立?)
├─ 否:略過
└─ 是:夜間? → 開 LED 60ms → 連拍 3 張 → 存 SD
└→ (選用) LINE Notify 圖片推播
只想快上線 → 選 A;場景複雜(光影變化多)→ 選 B。
// 有事件 → 連拍 3 張 + (選用)LINE 推播
void onEvent(){
// 夜間先補光
if (darkSceneEstimate()) { digitalWrite(4, HIGH); delay(60); }
String p1 = saveShot("event");
delay(150);
String p2 = saveShot("event");
delay(150);
String p3 = saveShot("event");
digitalWrite(4, LOW);
// (選用)任選一張上傳
// postLineImage(p2);
}
[門口管家 — 近24h]
事件數: 12 次
夜間比例: 58%
平均冷卻間隔: 19 s
上傳成功率: 97%
時段分布(每3小時)
00-03 | ▂ (1)
03-06 | (0)
06-09 | ▃▃ (2)
09-12 | ▅▅▅ (3)
12-15 | ▃▃ (2)
15-18 | ▅▅ (2)
18-21 | ███ (3)
21-24 | (0)
加分:每天 23:55 合成縮時影片(ffmpeg
可在電腦或手機做),或把 event_*.jpg
壓成 zip 備份。
目標:偵測「食盆區」有變化就連拍幾張,不嚇到貓狗、不過曝。
[食盆 ROI 區] → 亮度/邊緣 變化? → 是 → 補光 30ms → 連拍 3 張 → /DCIM/當日/
└→ (選) 每晚 21:00 產出當日精選 5 張
// 在 QQVGA 低解析灰階畫面上,只取 ROI 平均亮度
bool roiChanged(uint8_t* gray, int W, int H) {
int x0=40, y0=50, w=70, h=40; // 依食盆位置調整
long sum=0, n=0;
for(int y=y0;y<y0+h;y++)
for(int x=x0;x<x0+w;x++)
sum += gray[y*W+x], n++;
float avg = (float)sum/n;
static float last=-1;
bool changed = last>0 && fabs(avg-last) > 8.0; // 門檻看場景
last = avg;
return changed;
}
[寵物自拍 — 近7天]
每日入鏡張數: 12, 9, 15, 11, 8, 14, 13
進食高峰: 07:30–08:30、19:00–20:00
模糊率: 8%
最佳光線解析度組合: VGA + LED 40ms
不做偵測人臉、不跑 AI,只看「穿越順序」。
作法:在 低解析灰階 畫面上,設兩條水平帶狀區(A 在外、B 在內)。
A→B 算「進」、B→A 算「出」。
[低解析灰階畫面]
├─ 區域 A(門外一側)
└─ 區域 B(門內一側)
每幀算 A/B 的變化量
若連續幀出現 A→B → in_count++
若連續幀出現 B→A → out_count++
每次計數 → 存一張證明照到 SD(可略)
enum State { IDLE, TRIG_A, TRIG_B };
State st = IDLE;
bool changeA(), changeB(); // 用亮度或邊緣變化(類似 ROI 範例)
void handleFlow(){
switch(st){
case IDLE:
if(changeA()) st = TRIG_A;
else if(changeB()) st = TRIG_B;
break;
case TRIG_A:
if(changeB()){ in_count++; saveShot("in"); st = IDLE; }
else if(timeout()) st = IDLE;
break;
case TRIG_B:
if(changeA()){ out_count++; saveShot("out"); st = IDLE; }
else if(timeout()) st = IDLE;
break;
}
}
[客流計數 — 今日]
入店: 73 出店: 68 淨流入: +5
時段峰值: 12:00–13:00(入 21 / 出 18)
平均停留: 估 7–10 分(以 A→B→B 無動作時間粗算)
小提醒:這是概念級計數;若門口很窄且人靠得很近,可能會「同時觸發 A/B」。
改進方向:縮小 ROI、加冷卻、或改雙門框夾角配置。
穩定性:24h 連續運作 OK(掉線 < 1 次)
誤報率:門口管家 < 10%(日均)
成功率:拍照寫檔 98% 以上;LINE 推播 95% 以上
儲存策略:保留 7 天,自動清理
[任務] | 指標 | 結果
---------------+-----------+-------------------------
門口管家 | 誤報率 | 8.6%
寵物自拍 | 模糊率 | 8%(LED 40ms 後下降)
客流計數 | 峰值時段 | 12:00–13:00
系統穩定 | 24h 運行 | OK(重試 1 次)
health.json
到 SD(方便追查)config.json
(解析度/LED 時間/冷卻/ROI)→ 開機讀取/update
路由(上傳 .bin
→ 自行 OTA;需要額外空間)ESP32-CAM-SETUP
)提供簡易設定頁