1.算法描述
行人檢測技術(shù)已經(jīng)成為計算機(jī)視覺領(lǐng)域的關(guān)鍵研究方向。行人檢測的最重要的任務(wù)就是對行人目標(biāo)進(jìn)行準(zhǔn)確定位叠骑。行人檢測技術(shù)有很強(qiáng)的使用價值火本,可以與多人跟蹤、行人重識別等技術(shù)結(jié)合温学,應(yīng)用于汽車無人駕駛系統(tǒng)略贮、智能機(jī)器人、智能視頻監(jiān)控仗岖、人體行為分析逃延、人流量統(tǒng)計系統(tǒng)、智能交通領(lǐng)域轧拄。
目前的行人檢測任務(wù)主要為基于圖像特征的方法揽祥。基于圖像特征的方法檩电,主要通過手動構(gòu)造行人特征拄丰,如hog等,再結(jié)合svm是嗜、adaboost等分類器訓(xùn)練檢測器來實現(xiàn)行人檢測愈案。在實際場景下,多個行人與攝像頭之間的距離遠(yuǎn)近不一鹅搪,攝像頭捕獲的圖像中行人尺寸不同站绪,而現(xiàn)有檢測過程中的特征尺寸單一,無法覆蓋所有的待檢測行人尺寸丽柿,出現(xiàn)漏檢情況恢准,導(dǎo)致檢測效果不佳。另外甫题,在密集人群場景下馁筐,行人之間會出現(xiàn)重疊情況,檢測出多個目標(biāo)的候選區(qū)域框距離比較近時坠非,在最終去掉重復(fù)任務(wù)的檢測框時敏沉,容易誤除,導(dǎo)致密集行人檢測效果不佳炎码。
支持向量機(jī)(support vector machines, SVM)是二分類算法盟迟,所謂二分類即把具有多個特性(屬性)的數(shù)據(jù)分為兩類,目前主流機(jī)器學(xué)習(xí)算法中潦闲,神經(jīng)網(wǎng)絡(luò)等其他機(jī)器學(xué)習(xí)模型已經(jīng)能很好完成二分類攒菠、多分類,學(xué)習(xí)和研究SVM歉闰,理解SVM背后豐富算法知識辖众,對以后研究其他算法大有裨益卓起;在實現(xiàn)SVM過程中,會綜合利用之前介紹的一維搜索凹炸、KKT條件、懲罰函數(shù)等相關(guān)知識啤它。本篇首先通過詳解SVM原理蚕键,后介紹如何利用python從零實現(xiàn)SVM算法锣光。
實例中樣本明顯的分為兩類铝耻,黑色實心點不妨為類別一瓢捉,空心圓點可命名為類別二,在實際應(yīng)用中會把類別數(shù)值化搂漠,比如類別一用1表示桐汤,類別二用-1表示靶壮,稱數(shù)值化后的類別為標(biāo)簽腾降。每個類別分別對應(yīng)于標(biāo)簽1、還是-1表示沒有硬性規(guī)定抗果,可以根據(jù)自己喜好即可窖张,需要注意的是蚁滋,由于SVM算法標(biāo)簽也會參與數(shù)學(xué)運算,這里不能把類別標(biāo)簽設(shè)為0梢卸。
2.仿真效果預(yù)覽
matlab2022a仿真結(jié)果如下:
第一步:讀取圖片視屏序列
function [n_frames,I3] = func_readvedio(folder,list);
n_frames = 0;
for i=1:length(list)
I ?= imread(fullfile(folder,list(i).name));
I2 = rgb2gray(uint8(I));
I3(:,:,i) = I2;
n_frames ?= n_frames + 1;
end
這樣寫可以專門用來讀取連續(xù)編號的圖片序列作為視屏。
第二步:提取背景
對應(yīng)的代碼如下所示:
//以上就是求解圖像的差分
CDM(1:rows,1:cols,2:frames) = d(1:rows,1:cols,2:frames);
CDM(abs(CDM) < ?T)=0;
CDM(abs(CDM) >= T)=255;
//求CDM值
m=0;
for i=1:rows
for j=1:cols
for k=2:frames
if CDM(i,j,k) == 0
m(k)=1;
end
if CDM(i,j,k) == 255
m(k)=rand(1);
end ????????
end
position(i,j) = func_position(m);
end
end
//獲得背景
第三步:當(dāng)前圖片與背景的差
function images2 = func_subbackground(image,back,frames,T2);
rows = size(image,1); ??
cols = size(image,2);
for k=1:frames
images(1:rows,1:cols,k) ?= back(1:rows,1:cols)-image(1:rows,1:cols,k); ?
images2(1:rows,1:cols,k) = im2bw(images(1:rows,1:cols,k),T2);
end
這里求解差,并將得到的結(jié)果求二值圖
第四步:形態(tài)學(xué)處理
rows = size(image,1); ??
cols = size(image,2);
for k=1:frames
images3(1:rows,1:cols,k)=bwareaopen(image(1:rows,1:cols,k),10);
end
這里我們主要將視屏中的個別噪點去掉使畫面更加’干凈’恤批;
第五步:邊緣檢測
function images = func_edgecheck(image,frames);
rows = size(image,1); ???
cols = size(image,2);
for k = 1:frames
for i=2:rows
for j=2:cols
if image(i,j,k)==1 &&(image(i+1,j,k)==0||image(i-1,j,k)==0||image(i,j+1,k)==0||image(i,j-1,k)==0)
images(i,j,k)=255;
else
images(i,j,k)=0;
end
end
end
end
普通邊間求解法
統(tǒng)計人員像素并分析出對應(yīng)的密集度。
3.MATLAB核心程序
folder ????= 'Vedio\02\';
list ??????= dir('Vedio\02\*.jpg');
level ?????= 60;
level2 ????= 0.25;
level3 ????= 8000;%用來區(qū)分低密度還是中高密度的門限值
level4 ????= 1200;
flag ??????= 0;%1:低密度睛竣,0:高密度
density ???= 1;%定義一個密度變量酵颁,記錄不同時刻的密度變化
%step1:讀取圖片序列
[n_frames,I3] = func_readvedio(folder,list);
%step2:提取背景
back3 = func_getbackground(I3,n_frames,level);
rows = size(I3,1); ???
cols = size(I3,2);
clear ?folder list;
%由于是基于視屏的躏惋,所以下面采用一個循環(huán)的處理方法進(jìn)行處理,每次只處理一個圖片
for k = 1:n_frames%下面的處理都是基于逐幀的
disp('當(dāng)前幀數(shù)');k
%step3:背景差
images2(1:rows,1:cols,k) = func_subbackground(I3(1:rows,1:cols,k),back3,level2);
%step4:形態(tài)學(xué)處理
images3(1:rows,1:cols,k) = func_Xintai(images2(1:rows,1:cols,k));
%step5:統(tǒng)計前景像素數(shù)目
Num(k) = func_pixel(images3(1:rows,1:cols,k));
%低密度
%低密度
%低密度
%低密度
if Num(k) < level3%說明是低密度
flag ??????= 1; ???
%step6:邊緣檢測
images4(1:rows,1:cols,k) = func_edgecheck(images3(1:rows,1:cols,k));
%step7:統(tǒng)計前景邊緣像素數(shù)目
Num2(k) = func_pixel(images4(1:rows,1:cols,k));
if Num2(k) <level4
disp('人口密度很低,密度等級:1'); ???
density(k) = 1;
else
disp('人口密度低 ?扁位,密度等級:2');
density(k) = 2;
end ???
end
%高密度
%高密度
%高密度
%高密度 ???????
if Num(k) > level3%說明是中高密度
flag ??????= 0; ???
%人群密度特征提取
d=1;
[Energy8_0(k),Contrast8_0(k),Correlation8_0(k),Homogeneity8_0(k)] = func_different_L_features(images3(1:rows,1:cols,k),k,d);
level = 8; ???
%選取0度和90度的作為訓(xùn)練數(shù)據(jù)
[train1_data_0,train1_data_90,train2_data_0,train2_data_90,test_data_0,test_data_90]=func_loaddata(level);
%high_low = 1; %中密度分類值
%high_low = -1;%高密度分類值
%輸出結(jié)果為error=1域仇,說明不是該類暇务;輸出為0怔软,說明屬于某類型
%0度數(shù)據(jù)的訓(xùn)練
[error01,Output01] = func_classifer(train1_data_0,train2_data_0,test_data_0,1);
[error02,Output02] = func_classifer(train1_data_0,train2_data_0,test_data_0,-1);
%90度數(shù)據(jù)的訓(xùn)練
%[error901,Output901] = func_classifer(train1_data_90,train2_data_90,test_data_90,1); ???????????
%[error902,Output902] = func_classifer(train1_data_90,train2_data_90,test_data_90,-1); ????
if error01 == 0 & error02 == 1 ??
disp('人口密度高 ?挡逼,密度等級:4');
density(k) = 4;
end
if error01 == 1 & error02 == 0
disp('人口密度中 ?家坎,密度等級:3');
density(k) = 3;
end
end ???
figure(1);
imshow(I3(1:rows,1:cols,k));
title(['人口密度等級',num2str(density(k))]);
drawnow
end
if flag == 1
figure; ???
%1隨幀數(shù)變化前景像素數(shù)變化曲線
subplot(211);plot(Num,'b-*');title('隨幀數(shù)變化前景像素數(shù)變化曲線');
%3前景人數(shù)與人數(shù)的擬合曲線
%曲線擬合
xdata1=1:length(Num);
a1=polyfit(xdata1,Num,1);
y1=polyval(a1,xdata1);
%人數(shù)曲線擬合
x1=1:8;
y1=5*a1(1)*x1+a1(2);
subplot(212);plot(y1,x1,'r-*');
title('前景人數(shù)與人數(shù)的擬合曲線');
end