時(shí)人體異常行為檢測系統(tǒng)設(shè)計(jì):背景差分與SVM分類實(shí)踐)
簡介一套基于 MATLAB 實(shí)現(xiàn)的實(shí)時(shí)人體異常行為檢測識(shí)別系統(tǒng)附有圖形用戶界面面向視頻監(jiān)控與安全防范場景也適合計(jì)算機(jī)視覺方向的項(xiàng)目實(shí)戰(zhàn)學(xué)習(xí)。資源壓縮包共包含 769 個(gè)文件其中 6 個(gè) .m 文件是主程序與函數(shù)源碼1 個(gè) .fig 保存 GUI 界面布局3 個(gè) .avi 與 1 個(gè) .mp4 提供步行、慢跑、快跑等測試視頻755 個(gè) .jpg 圖片可用于人體樣本與行為分類訓(xùn)練測試此外還有說明文檔整體約 18.16MB便于快速下載與解壓使用。目前已有 265 人瀏覽學(xué)習(xí)。可運(yùn)行主界面并調(diào)用攝像頭或視頻文件進(jìn)行檢測通過源碼可以理解實(shí)時(shí)視頻幀讀取、人體目標(biāo)檢測、運(yùn)動(dòng)特征提取以及異常行為判別的完整流程同時(shí)還能借鑒 GUI 中視頻輸入控制、結(jié)果展示、參數(shù)調(diào)節(jié)等模塊的編寫方法。對(duì)希望盡快搭建人體異常行為預(yù)警原型或想在 MATLAB 環(huán)境下深入掌握計(jì)算機(jī)視覺與 GUI 開發(fā)的讀者都是一份不錯(cuò)的實(shí)踐資料。1. 實(shí)時(shí)人體異常行為檢測為什么說 MATLAB GUI 是快速驗(yàn)證的優(yōu)選路徑監(jiān)控大屏前坐一天真正需要關(guān)注的異常往往只有幾秒——跌倒、奔跑、揮手、打架。實(shí)時(shí)人體異常行為檢測要做的就是從連續(xù)的圖像流里把它們自動(dòng)挑出來并給出提示。這套帶 GUI 的 MATLAB 完整工程就是圍繞這個(gè)場景落地的讀取攝像頭或視頻文件實(shí)時(shí)檢測異常行為在界面里框出目標(biāo)并觸發(fā)報(bào)警全程不需要部署推理服務(wù)器一臺(tái)裝有 MATLAB 的普通電腦就能跑通。資源適合三類人正在做 MATLAB 圖像處理大作業(yè)的學(xué)生、需要快速驗(yàn)證算法的研究員、以及想把人體檢測 demo 改造成可演示原型的一線工程師。代碼結(jié)構(gòu)清楚換攝像頭、調(diào)閾值、加行為類別都留了明確的修改入口。2. 姿態(tài)提取與動(dòng)作特征算法選型和技術(shù)底座2.1 背景差分做人形檢測前先把“動(dòng)起來的東西”找出來這套系統(tǒng)的前置任務(wù)是把人體從背景里分離出來。常見做法是用混合高斯背景模型也就是 MATLAB 里vision.ForegroundDetector封裝好的那個(gè)實(shí)現(xiàn)。它會(huì)對(duì)畫面里每個(gè)像素維護(hù)多個(gè)高斯分布用來描述該位置在不同時(shí)刻的顏色波動(dòng)哪些分布占比高就判定為背景偏離背景模型的像素就標(biāo)記為前景也就是“當(dāng)前幀有什么東西在動(dòng)”。% 創(chuàng)建前景檢測器這里建議保留句柄方便后續(xù)調(diào)參 fgDetector vision.ForegroundDetector( ... NumTrainingFrames, 50, ... % 取前50幀做背景訓(xùn)練 AdaptLearningRate, 0.005, ... % 背景更新速度調(diào)小則更“記舊賬” NumGaussians, 3, ... % 每個(gè)像素用3個(gè)高斯分量描述 MinimumBackgroundRatio, 0.6); % 某分布累計(jì)占比到0.6即視為背景這段代碼是系統(tǒng)的第一道閘門。NumTrainingFrames決定系統(tǒng)開機(jī)后需要多少幀來建立干凈的背景模型值設(shè)大一點(diǎn)能減少初始階段的鬼影但開機(jī)后等待時(shí)間變長。AdaptLearningRate是背景模型對(duì)場景變化的學(xué)習(xí)速率0.005 屬于中檔室內(nèi)固定攝像頭下表現(xiàn)平穩(wěn)室外有樹葉晃動(dòng)、水面反光時(shí)需要降到 0.001~0.002否則這些“非人”運(yùn)動(dòng)會(huì)被持續(xù)吸收為背景。NumGaussians用 3 個(gè)分量就能覆蓋大多數(shù)固定攝像頭場景分量越多越能處理多模態(tài)背景但計(jì)算量也會(huì)上浮。前景掩碼輸出后通常要接一次形態(tài)學(xué)閉運(yùn)算把人體內(nèi)部因?yàn)橐路y理產(chǎn)生的破洞連通也把邊緣毛刺去掉。這個(gè)步驟在代碼里用vision.MorphologicalClose做結(jié)構(gòu)元素選 7×7 矩形太小連通不完整太大容易把相鄰兩個(gè)人連成一個(gè)目標(biāo)。調(diào)參時(shí)可以先看單幀掩碼效果再批量跑不要上來就調(diào)分類器。2.2 人體檢測與關(guān)鍵點(diǎn)優(yōu)先考慮計(jì)算量而非精度背景差分能拿到“有東西在動(dòng)”但拿不到“這是一整個(gè)人”。下一步要在前景區(qū)域上做人體框檢測。MATLAB 自帶peopleDetectorACF、peopleDetectorCascade和基于深度學(xué)習(xí)的檢測器CPU 環(huán)境下優(yōu)先用 ACF幀率比深度學(xué)習(xí)模型高一個(gè)數(shù)量級(jí)檢測精度對(duì)監(jiān)控場景足夠。% 對(duì)當(dāng)前幀做人形檢測這里選用ACF檢測器 detector peopleDetectorACF(caltech); [bboxes, scores] detect(detector, I); % ACF分?jǐn)?shù)大于閾值的框才保留閾值取決于場景和采樣間隔 keep scores 2; bboxes bboxes(keep, :); scores scores(keep);這段代碼的要點(diǎn)在于“分?jǐn)?shù)閾值”并沒有通用值。ACF 返回的 scores 在不同視頻源、不同分辨率下分布差異很大我一般會(huì)先跑一段帶標(biāo)注的錄像統(tǒng)計(jì)正常幀和異常幀的分?jǐn)?shù)分布再定閾值。閾值設(shè)太低背景里一些類人紋理會(huì)被框出來設(shè)太高晚上低照度下真實(shí)的人反而漏檢。這里不做深度學(xué)習(xí)關(guān)鍵點(diǎn)檢測是因?yàn)楸緢鼍爸恍枰说恼w框和重心位置不需要精確到腳踝、手腕的骨骼坐標(biāo)。實(shí)時(shí)性優(yōu)先精度夠用就行。2.3 動(dòng)作特征設(shè)計(jì)把框的變化翻譯成可判別的數(shù)值拿到人體框后異常行為的判別依據(jù)來自框本身的幾何特征。跌倒最典型的特征是人體高寬比從站姿的 4~5 急劇掉到 0.3 以下同時(shí)重心快速下移并在地面高度附近停留。奔跑的特征是重心水平位移速度大且連續(xù)若干幀保持高速。揮拳這類上半身行為則表現(xiàn)為框內(nèi)上部區(qū)域的像素變化頻繁。把這幾個(gè)信號(hào)組織成特征向量分類器才有東西可學(xué)。% 從人體框與歷史信息中提取單幀特征prevBbox來自上一幀 function feat extractFrameFeat(bbox, prevBbox, ratioThreshold) w bbox(3); h bbox(4); cx bbox(1) w / 2; cy bbox(2) h / 2; ratio h / max(w, eps); % 高寬比跌倒時(shí)劇烈下降 speed hypot(cx - prevBbox(1), cy - prevBbox(2)); % 重心水平位移速度 areaChange (w * h) / max(prevBbox(3) * prevBbox(4), eps); % 低高寬比 低速 重心偏低是“倒地靜止”的聯(lián)合信號(hào) fallHint double(ratio 1.2 speed 0.08 cy size(prevBbox, 1) * 0.6); feat [ratio, speed, areaChange, cx / 640, cy / 480, fallHint]; end特征里最后匯總了 5 個(gè)連續(xù)量加 1 個(gè)邏輯量。ratio直接反映姿勢speed反映運(yùn)動(dòng)劇烈程度areaChange反映目標(biāo)在前進(jìn)或站立時(shí)的面積擴(kuò)張。cx/640、cy/480這兩個(gè)歸一化位置分量很有用監(jiān)控畫面里不同位置發(fā)生異常后續(xù)分類器能借助位置信息區(qū)分“在墻邊滑倒”和“在通道里快跑”。fallHint是我在調(diào)試中發(fā)現(xiàn)非常有效的經(jīng)驗(yàn)特征它把“低高寬比低速位于畫面下半部”三個(gè)條件合并成一個(gè)維度比讓 SVM 自己去組合這三個(gè)量更容易收斂。實(shí)際項(xiàng)目中我還會(huì)追加一個(gè)“地面停留幀數(shù)”特征用于區(qū)分倒地不起和彎腰撿東西。2.4 滑動(dòng)窗口與統(tǒng)計(jì)壓縮避免把時(shí)序問題當(dāng)成單幀問題單幀特征的缺陷是抖動(dòng)太大。站姿的人彎一下腰高寬比瞬間就變了。所以系統(tǒng)里要引入時(shí)間維度做法是維護(hù)一個(gè)滑動(dòng)窗口存儲(chǔ)近 30 幀的特征向量再對(duì)窗口內(nèi)的每個(gè)特征取均值、最大值、最小值和標(biāo)準(zhǔn)差最終壓成一個(gè)低維向量再送進(jìn)分類器。這里有個(gè)工程取舍直接把 30×6180 維數(shù)據(jù)丟給分類器理論上可行但訓(xùn)練集不大時(shí)特別容易過擬合。壓縮成統(tǒng)計(jì)量后特征維度降到 24 維SVM、隨機(jī)森林都能在幾百個(gè)樣本上穩(wěn)定收斂。窗口長度選 30 幀對(duì)應(yīng) 1 秒既足夠覆蓋一次跌倒的完整過程又不會(huì)因?yàn)榇翱谶^長把跑步這類快速行為平滑掉。窗口滑動(dòng)的實(shí)現(xiàn)不做逐幀重算用隊(duì)列結(jié)構(gòu)先進(jìn)先出每來一幀就更新隊(duì)尾、彈出隊(duì)首再重算統(tǒng)計(jì)量計(jì)算開銷很小。3. 系統(tǒng)實(shí)現(xiàn)GUI 界面、實(shí)時(shí)視頻流與檢測鏈路接線3.1 App Designer 搭建界面用 UIAxes 而不是 axes這套系統(tǒng)的圖形界面用 App Designer 實(shí)現(xiàn)。主界面包含一塊視頻顯示區(qū)、開始/停止按鈕、異常狀態(tài)指示燈、以及一個(gè)顯示當(dāng)前行為類別的文本框。組件選擇上有一個(gè)容易被忽視的點(diǎn)視頻顯示必須用 UIAxes不能用傳統(tǒng) axes。UIAxes 設(shè)計(jì)目標(biāo)就是支持高頻的imshow刷新和交互回調(diào)傳統(tǒng) axes 在新版 MATLAB 中只是兼容存在實(shí)時(shí)刷新時(shí)性能瓶頸會(huì)很突出。界面的回調(diào)邏輯并不復(fù)雜。開始按鈕的回調(diào)里創(chuàng)建視頻讀取對(duì)象和定時(shí)器停止按鈕的回調(diào)里清空定時(shí)器并釋放攝像頭占用。狀態(tài)指示燈用一個(gè) Lamp 組件正常時(shí)亮綠色異常時(shí)亮紅色同時(shí)文本框打印異常類型和置信度。參數(shù)區(qū)放三個(gè)可編輯字段檢測閾值、報(bào)警幀數(shù)、視頻源編號(hào)方便現(xiàn)場調(diào)試。3.2 用 timer 驅(qū)動(dòng)采集循環(huán)讓 UI 在檢測過程中保持可操作實(shí)時(shí)系統(tǒng)最忌諱在主線程里寫死循環(huán)。很多第一次接觸這個(gè)資源的人會(huì)習(xí)慣性寫成while hasFrame(vidObj) ... end結(jié)果界面一運(yùn)行就卡死按鈕點(diǎn)不動(dòng)、窗口拖不動(dòng)。原因很簡單MATLAB 的 UI 事件循環(huán)被 while 占用根本沒機(jī)會(huì)處理鼠標(biāo)消息。正確做法是讓定時(shí)器對(duì)象按固定周期回調(diào)每次回調(diào)只處理一幀。% 在“開始檢測”回調(diào)中創(chuàng)建定時(shí)器Period單位是秒 vidSrc webcam(app.CameraIDEditField.Value); % 打開指定攝像頭 tImg timer( ... TimerFcn, (~,~) frameLoop(app), ... % 每周期執(zhí)行一次幀處理 Period, 1/30, ... % 目標(biāo)30幀/秒 ExecutionMode, fixedRate); % 固定速率不累計(jì)延遲 start(tImg);這段代碼里有幾個(gè)細(xì)節(jié)。ExecutionMode設(shè)為fixedRate后每幀間隔按絕對(duì)時(shí)間計(jì)算不會(huì)像fixedSpacing那樣因?yàn)榛卣{(diào)執(zhí)行時(shí)間波動(dòng)而漂移?;卣{(diào)中只做三件事讀取一幀、調(diào)檢測函數(shù)、刷新畫面。如果檢測函數(shù)跑得太慢寧可讓Period放大到 1/20 也不要讓 UI 卡頓。攝像頭對(duì)象在停止回調(diào)中要顯式clear vidSrc否則下次啟動(dòng)會(huì)報(bào)“攝像頭已被占用”這是 MATLAB 圖像采集最常見的翻車點(diǎn)之一。3.3 檢測與顯示解耦跳幀檢測的接線方式實(shí)時(shí)鏈路里最大的性能矛盾來自檢測耗時(shí)。背景差分加 ACF 檢測每幀大約需要 40~80ms這就注定無法在每幀都完整檢測。我的做法是每 3 幀做一次完整檢測中間兩幀只刷新畫面不重新檢測。畫面刷新用上一幀的結(jié)果疊加框和標(biāo)簽視覺上基本無感但系統(tǒng)整體幀率能穩(wěn)定在 20fps 以上。定時(shí)器回調(diào)里用一個(gè)幀計(jì)數(shù)變量frameIdx模 3 為 0 時(shí)執(zhí)行檢測流程否則直接顯示原始幀。檢測函數(shù)內(nèi)部還要做一步“滯后處理”當(dāng)前檢測不到人體而上一幀檢測到時(shí)不立刻清空畫面而是用vision.KalmanFilter預(yù)測上一幀的框位置繼續(xù)顯示 5 幀等目標(biāo)重新出現(xiàn)。這一步能顯著減少跳繩、拍手這類動(dòng)作產(chǎn)生的目標(biāo)閃爍。真實(shí)項(xiàng)目里“檢測目標(biāo)在畫面里跳進(jìn)跳出”比“檢測不到”更影響觀感卡爾曼平滑是性價(jià)比很高的補(bǔ)丁。4. 分類器訓(xùn)練與調(diào)參從特征到異常判定的完整閉環(huán)4.1 構(gòu)造訓(xùn)練集正負(fù)樣本怎么采集最省力分類器的輸入是 2.4 節(jié)生成的統(tǒng)計(jì)壓縮特征。單樣本的結(jié)構(gòu)可以描述為下表特征組包含內(nèi)容維度高寬比統(tǒng)計(jì)均值、最大值、最小值、標(biāo)準(zhǔn)差4重心速度統(tǒng)計(jì)均值、最大值、最小值、標(biāo)準(zhǔn)差4面積變化統(tǒng)計(jì)均值、最大值、最小值、標(biāo)準(zhǔn)差4位置統(tǒng)計(jì)歸一化 x、y 的均值與標(biāo)準(zhǔn)差4倒地提示統(tǒng)計(jì)滑動(dòng)窗口內(nèi) fallHint 的均值1地面停留幀數(shù)窗口內(nèi)低重心且低速的總幀數(shù)1首尾幀特征窗口首幀與尾幀的高寬比、速度4合計(jì) 22 維。正樣本收集方式建議直接錄制異常演示視頻人工標(biāo)注行為開始和結(jié)束的幀號(hào)然后截取窗口生成樣本。負(fù)樣本來源更廣正常行走、站立聊天、彎腰整理東西、拿快遞等日常動(dòng)作都要覆蓋。容易犯的錯(cuò)誤是只錄“站著不動(dòng)”作為負(fù)樣本導(dǎo)致分類器把“任何運(yùn)動(dòng)”都視為異常誤報(bào)率爆炸。負(fù)樣本里一定要包含彎腰、坐下、下蹲這類與跌倒外觀接近的動(dòng)作。4.2 SVM 訓(xùn)練與參數(shù)語義樣本準(zhǔn)備好后訓(xùn)練 SVM 二分類器。MATLAB 的fitcsvm是核心入口參數(shù)注釋如下% 訓(xùn)練二分類支持向量機(jī)檢測異常行為 mdl fitcsvm(featMat, labels, ... KernelFunction, rbf, ... % RBF核能刻畫非線性決策邊界 BoxConstraint, 10, ... % 增大約束減小訓(xùn)練誤差但防過擬合需配合交叉驗(yàn)證 Standardize, true, ... % 標(biāo)準(zhǔn)化各維度防止高寬比壓倒速度特征 KernelScale, auto, ... % 自動(dòng)估計(jì)RBF核寬度 CrossVal, on, ... % 開啟10折交叉驗(yàn)證 KFold, 10); accuracy 1 - kfoldLoss(mdl);BoxConstraint是這條代碼里最值得解釋的參數(shù)。它控制對(duì)誤分類樣本的懲罰力度值越大訓(xùn)練時(shí)越努力把每一個(gè)樣本都分對(duì)但決策邊界會(huì)變得復(fù)雜泛化能力下降值越小邊界更平滑能容忍少量難分樣本。10 這個(gè)初值是我在類似特征維度下的常用起點(diǎn)訓(xùn)練完先看交叉驗(yàn)證準(zhǔn)確率再在 1~100 之間對(duì)數(shù)掃描兩輪。Standardize必須設(shè)為 true否則高寬比這個(gè)量綱在幾十的量級(jí)上會(huì)直接支配速度特征。RBF 核默認(rèn)適合大多數(shù)情況不要急著換多項(xiàng)式核或線性核。4.3 隨機(jī)森林作為備選什么時(shí)候不該迷信 SVM資源里同時(shí)提供了隨機(jī)森林的備選實(shí)現(xiàn)用fitcensemble打包 Bagging 樹。SVM 在小樣本、特征維度低時(shí)速度優(yōu)勢明顯但它的決策邊界依賴核函數(shù)的選擇調(diào)參經(jīng)驗(yàn)不足的人容易在核寬度上踩坑。隨機(jī)森林幾乎沒有需要精細(xì)調(diào)整的參數(shù)NumLearningCycles設(shè) 100各樹用隨機(jī)特征子集默認(rèn)設(shè)置下就能得到穩(wěn)定結(jié)果缺點(diǎn)是在本場景中推理速度略慢單幀大約多 2~5ms。我的經(jīng)驗(yàn)做法是樣本量少于 300 時(shí)優(yōu)先 SVM樣本量過千后優(yōu)先隨機(jī)森林這兩類分類器在這個(gè)任務(wù)上的準(zhǔn)確率差距通常不超過 3 個(gè)百分點(diǎn)不必追求“最優(yōu)算法”。4.4 時(shí)序投票在分類器后加一道后悔藥分類器輸出的是單窗口的決策但一兩個(gè)異常窗口并不能構(gòu)成真正的行為。工程上我習(xí)慣在分類器后面再加投票邏輯連續(xù) 5 個(gè)滑動(dòng)窗口中有 3 個(gè)判定為異常才真正觸發(fā)報(bào)警。% 維護(hù)一個(gè)5元素的環(huán)形緩沖記錄最近5個(gè)窗口的判定結(jié)果 function isAlarm voteAlarm(app, currentVote) app.voteBuf [app.voteBuf(2:end), currentVote]; % 隊(duì)列滾動(dòng) if sum(app.voteBuf) 3 % 5幀中有3幀異常 isAlarm true; else isAlarm false; end end這段代碼把瞬時(shí)誤判擋在了報(bào)警門外。voteBuf初始化為全 0 的 1×5 數(shù)組每來一個(gè)新判定就推進(jìn)一位。閾值為什么選 3 而不是 5因?yàn)檎鎸?shí)跌倒過程中前期有低高寬比特征的幀數(shù)通常只有 20 幀左右窗口切分的邊界效應(yīng)會(huì)導(dǎo)致部分窗口落在動(dòng)作前段、特征不夠典型。5 取 3 既保證連續(xù)性又保留一定容錯(cuò)。報(bào)警后系統(tǒng)會(huì)自動(dòng)保存觸發(fā)前后各 10 秒的視頻片段方便事后復(fù)核這個(gè)功能在演示時(shí)特別加分。5. 實(shí)時(shí)系統(tǒng)的常見坑性能瓶頸、誤檢與工程細(xì)節(jié)排查5.1 點(diǎn)擊開始按鈕后界面卡死現(xiàn)象點(diǎn)擊“開始檢測”后整個(gè)窗口失去響應(yīng)拖動(dòng)窗口出現(xiàn)“白框”只能強(qiáng)制關(guān)閉 MATLAB。原因回調(diào)函數(shù)里用了while循環(huán)逐幀讀視頻循環(huán)體內(nèi)沒有讓出 UI 事件處理MATLAB 界面線程被完全阻塞。這個(gè)坑幾乎所有第一次實(shí)現(xiàn)實(shí)時(shí) GUI 的人都會(huì)遇到不是代碼邏輯錯(cuò)誤而是事件模型用錯(cuò)了。解決把 while 循環(huán)改成 timer 定時(shí)驅(qū)動(dòng)每周期只處理一幀?;卣{(diào)函數(shù)保持短小不要在回調(diào)里做耗時(shí)的模型推理、特征可視化等操作把耗時(shí)工作拆到獨(dú)立的檢測函數(shù)中回調(diào)只負(fù)責(zé)取結(jié)果和刷新 UI。5.2 彎腰撿東西被判定為跌倒現(xiàn)象畫面里有人正常彎腰撿文件系統(tǒng)連續(xù)觸發(fā)跌倒報(bào)警頻繁誤報(bào)。原因只用了單幀高寬比特征。彎腰和跌倒前期的外觀非常接近高寬比都明顯下降僅靠形狀無法區(qū)分。解決給判定增加時(shí)序條件跌倒必須滿足重心先快速下移、隨后 5 幀以上維持在畫面低處且?guī)缀醪灰苿?dòng)。也就是說只把“倒地”而不是“彎腰”判為異常。特征向量中需要加入地面停留幀數(shù)與重心下降速度兩個(gè)維度并在投票緩沖里要求連續(xù)窗口滿足低速條件誤報(bào)就能壓下去。5.3 接入深度學(xué)習(xí)姿態(tài)模型后幀率暴跌現(xiàn)象把檢測段換成 OpenPose 一類關(guān)鍵點(diǎn)模型后幀率從 25fps 跌到 3fps實(shí)時(shí)性完全喪失。原因深度學(xué)習(xí)關(guān)鍵點(diǎn)模型的單幀推理耗時(shí) 200~400ms而定時(shí)器周期只有 33ms計(jì)算量遠(yuǎn)超系統(tǒng)吞吐能力。解決放棄在每幀上做關(guān)鍵點(diǎn)提取只對(duì) ACF 人體框做輕量特征計(jì)算確有骨骼需求時(shí)每 10 幀做一次關(guān)鍵點(diǎn)推理中間用速度與位置插值補(bǔ)齊。用深度學(xué)習(xí)不是不行但要把它放到“低頻輔助”的位置而不是主鏈路里。另外我一般會(huì)檢查gpuDevice是否可用MATLAB 的深度學(xué)習(xí)推理在 CPU 和 GPU 上耗時(shí)差距近 10 倍偶爾是環(huán)境配置不到位導(dǎo)致速度異常。5.4 人體靜坐 40 秒后從前景中消失現(xiàn)象監(jiān)控畫面中有人坐在椅子上長時(shí)間不動(dòng)幾十秒后前景掩碼里再也找不到這個(gè)人系統(tǒng)認(rèn)為這是一張空畫面。原因背景模型的AdaptLearningRate設(shè)得偏大坐姿的人被緩慢吸收為背景。前景檢測器本身沒有“這曾經(jīng)是個(gè)人”的記憶像素顏色一旦被納入背景分布再想分離出來就需要下一次運(yùn)動(dòng)。解決把AdaptLearningRate降到 0.002 左右同時(shí)定期重置背景模型。更穩(wěn)妥的方法是疊加一層基于 ACF 的人體區(qū)域檢測即使前景掩碼為空只要 ACF 能檢測到人形輪廓就強(qiáng)制保留該區(qū)域的檢測狀態(tài)。這個(gè)兜底邏輯對(duì)防漏檢非常有效代價(jià)是每幀多幾十毫秒計(jì)算。5.5 換臺(tái)電腦后報(bào)錯(cuò)找不到工具箱或函數(shù)現(xiàn)象代碼在自己的機(jī)器上跑得好好的換一臺(tái)電腦就報(bào)Undefined function vision.ForegroundDetector。原因目標(biāo)機(jī)沒有安裝 Computer Vision Toolbox 或 Image Processing Toolbox。MATLAB 的 license 是按工具箱授權(quán)的腳本本身不攜帶依賴這個(gè)問題在把代碼發(fā)給別人或找人代跑程序時(shí)頻繁出現(xiàn)。解決交付前在命令行執(zhí)行ver查看已安裝工具箱列表明確標(biāo)注依賴項(xiàng)。如果目標(biāo)用戶沒有完整 MATLAB 授權(quán)就用 MATLAB Compiler 打獨(dú)立 exe目標(biāo)機(jī)只需要安裝對(duì)應(yīng)版本的 MATLAB Runtime。需要特別確認(rèn)的是 Runtime 的版本號(hào)必須與打包時(shí)一致R2024a 打包的程序在 R2023b 的 Runtime 上無法運(yùn)行。6. 進(jìn)階把原型推向?qū)崟r(shí)與交付的最后一公里6.1 用卡爾曼跟蹤補(bǔ)足跳幀空窗跳幀檢測雖然保住了幀率但檢測結(jié)果天然帶有間隔。與其等待每 3 幀做一次完整檢測不如在中間幀用卡爾曼濾波器預(yù)測目標(biāo)的運(yùn)動(dòng)軌跡。vision.KalmanFilter的構(gòu)造需要指定運(yùn)動(dòng)模型和數(shù)據(jù)維度對(duì)矩形框跟蹤用 4 維狀態(tài)就可以中心點(diǎn) x、y框?qū)?、框高? 卡爾曼濾波器的初始化與單步預(yù)測 kal vision.KalmanFilter(ConstantVelocity, ... StateCovariance, 10*eye(4), ... ProcessNoise, 1e-2, ... % 過程噪聲越大越“相信測量” MeasurementNoise, 1e-1); % 測量噪聲越大越“懷疑檢測框” predBox kal(bboxes(1, :)); % 每次調(diào)用同時(shí)完成預(yù)測和修正過程噪聲與測量噪聲是一對(duì)相互作用的值測量噪聲調(diào)大濾波器會(huì)更平滑地跟隨檢測框但響應(yīng)延遲增加過程噪聲調(diào)大跟蹤更積極但也更容易被誤檢框帶偏。經(jīng)驗(yàn)上先固定測量噪聲為 1e-1再掃描過程噪聲。跟蹤器的輸出不參與特征計(jì)算只用于畫面疊加和報(bào)警連續(xù)性判斷能避免檢測器本身的框抖動(dòng)放大分類器誤判。6.2 把 demo 打包成獨(dú)立 exe原型驗(yàn)證完成后如果要在現(xiàn)場電腦上演示直接用 MATLAB 打開工程是最省事的方式但對(duì)方不一定有完整工具箱。打包是更穩(wěn)妥的交付形態(tài)。在 MATLAB 里進(jìn)入compiler.build.standaloneApplication流程主函數(shù)包含創(chuàng)建 GUI 的入口工具會(huì)自動(dòng)拉取依賴。需要提前檢查兩點(diǎn)一是攝像頭采集支持包是否在依賴列表里二是確認(rèn)打包機(jī)與目標(biāo)機(jī) Runtime 版本一致。我踩過一次 Runtime 版本不匹配的坑打包后 exe 一運(yùn)行就閃退排查了近一個(gè)小時(shí)才發(fā)現(xiàn)是 Runtime 裝錯(cuò)了版本從那以后每次打包前都強(qiáng)制檢查version -runtime并在交付說明里寫明 Runtime 版本號(hào)。希望這套系統(tǒng)的拆解記錄能幫你在復(fù)現(xiàn)和改造時(shí)少走彎路尤其是 GUI 實(shí)時(shí)性這個(gè)最隱蔽的坑早繞開早省心。本文還有配套的精品資源點(diǎn)擊獲取