天天看點

一段很有意思小代碼:視訊中提取心率

通過功率譜的方法估計視訊中人臉的心率

原理:

由麻省理工學院多媒體實驗室提出的,基于光電容積脈搏波描記( Photoplethysmography,PPG)原理,結合獨立成分分析,利用人面部視訊測量出了心率,這種方法與被測試者是無接觸的。PPG原理就是血液對光的吸收率大于周圍組織,是以血容量的改變會影響血液對光的吸收程度。

1981年,Nijboer等提出PPG信号的強度會受到血管運動、血液容量和紅血球的位置等因素的影響。随着對PPG信号的研究越來越多,人們在PPG信号中發現了呼吸、心率等多種頻率的信号。呼吸時,靜脈血液由胸部起伏産生的壓力送回心髒,産生了與呼吸同步的血液灌注波動,是以PPG信号中包含與呼吸同頻率的信号啊。PPG信号由于心髒的周期性波動引起外周血管内血容量周期性變化而呈現周期性,是以通過分析PPG信号可以得到心率資訊

2010年美國麻省理工學院多媒體實驗室通過對PPG信号的研究,開創性的提出了基于人臉視訊的脈搏測量方法。他通過提取心髒跳動引起的人臉膚色的微弱變化來測量心率。這種方法采用非接觸式測量,消除了傳統儀器測量與患者接觸而産生的不适感。但是該方法測量的是人臉的顔色的微小變化,是以對光照的改變比較敏感

根據光電容積脈搏波描記PPG原理,人的膚色會随着血液容量的變化發生變化,而血液容量的改變主要是由于心髒跳動引起的充血和放血造成的。是以從視訊中提取心率,可以将人臉的彩色視訊中的膚色随時間變化做為觀察信号,在不同波長的光照下,血液吸收的光和反射的光會有細微的變化,表現為脈搏波PPG信号振幅的變化。

血液對波長550nm的光的吸收能力最強,其中,血液對紅色光的吸收能力最弱,對綠色光的吸收能力最強,是以錄制視訊時的R、G、B傳感器采集到的觀察信号中,觀察綠色光通道來識别PPG信号效果最好。在視訊的每一幀取一個相同位置的ROI框,計算框内RGB綠色通道的平均值作為此幀對應時刻的采樣點,在得到GREEN通道的時域信号之後,通過濾波器,之後得到濾波後的信号的功率譜,功率譜峰值對應的橫坐标即為每秒的心跳數。

整個流程如下圖:

一段很有意思小代碼:視訊中提取心率

内容:

1.讀取視訊

以圖檔的方式将視訊按幀儲存于檔案夾figure内

2. ROI區域定位

顯示第一幀圖像,在第一幀圖像内滑鼠選點,确定ROI區域。因為人面部動脈血管主要分布在鼻翼兩側和嘴四周,所主要選取臉頰部分作為人臉檢測心率的ROI區域(這裡就不放臉臉的實驗圖了,以手腕代替-_-其實都差不多)

一段很有意思小代碼:視訊中提取心率
[x,y]=ginput(1);  %點選滑鼠選點
x0=[x-len,y-len];
ROI = [x0(1)-len, x0(2)-len, 2*len, 2*len];
rectangle ('Position', ROI, 'EdgeColor', 'R', 'LineWidth', 2)
hold off
x0=round(x0);
Y=imcrop(image,[x0(1),x0(2),len,len]);
           

3.獲得RGB曲線

通過人臉的定位及跟蹤,确定ROI區域後,取ROI區域所有像素點像素值的平均值,做出ROI區域内時域的R、G、B值的曲線

一段很有意思小代碼:視訊中提取心率
file_path =  'E:\研一下課程\醫學信号處理\實驗三\提取心率\figure\';% 圖像檔案夾路徑
file_name='original_frame';
suffix='.bmp';
img_path_list = dir([file_path,'*.bmp']);%擷取該檔案夾中所有jpg格式的圖像
img_num = length(img_path_list);%擷取圖像總數量
if img_num > 0 %有滿足條件的圖像
        for j = 1:img_num %逐一讀取圖像
            order_num=num2str(j);
            total_path=strcat(file_path,file_name,order_num,suffix);
            image =  imread(total_path);
            image=double(image);
            Y=imcrop(image,[x0(1),x0(2),len,len]);
            %Y=imcrop(image,[676,333,20,20]);
            R=Y(:,:,1);
            G=Y(:,:,2);
            B=Y(:,:,3);
            r(j)=mean(mean(R));%紅色均值
            g(j)=mean(mean(G));%綠色均值
            b(j)=mean(mean(B));%藍色均值
        end
end
           

通過觀察多個視訊ROI區域的RGB三通道像素值的均值曲線可以看出,綠色通道(green通道)的曲線具噪聲較小,但是由于光照等外部環境及人在視訊錄制過程中的移動産生的誤差導緻曲線會出現很多毛刺,影響了後續提取心率的計算。

4.濾波

設計巴特沃茲帶通濾波器,周歲内嬰兒心跳頻率大約為:100-120 次/分,故而濾波器通帶頻率近似設定為1.5~2Hz(成人的話頻率适當更改,1-2Hz足夠了)。

fp=[1.2,2];    %通帶
fst=[0.5,3];   %阻帶
wp=2.*fp./fs;    %設定通帶頻率
ws=2.*fst./fs;   %設定阻帶頻率
ap=1;            %設定通帶波紋系數
as=20;           %設定阻帶波紋系數 
[n,wc]=buttord(wp,ws,ap,as); %巴特沃茲帶通濾波器,n為濾波器階數
[b0,a0]=butter(n,wc);
[h,w]=freqz(b0,a0);

           

5.通過帶通濾波器之後,可以得到G通道信号的時域圖像.再對時域信号進行FFT,計算面部信号頻譜,然後計算面部信号經過信号處理之後得到的功率譜

一段很有意思小代碼:視訊中提取心率

用find函數讀取上圖資料中第一個峰值,得到相應橫坐标,x*60即為心率,經過計算,就可以得到心率,我一般在88左右。

超簡單

雖然跟那些專業的比差很多,但也可以拿去忽悠外行人不是

繼續閱讀