real time smartphone camera processing v2

1 次查看(过去 30 天)
I have this code:
url = 'http://192.168.1.108:8080/shot.jpg'; % single frame source
cam = imread(url); % read source
% Parameters to play with
WINDOW_SECONDS = 4;
BPM_L = 40; BPM_H = 230; % [bpm] Valid heart rate range
FILTER_STABILIZATION_TIME = 1; % [s] Filter startup transient
CUT_START_SECONDS = 0; % [s] Initial signal period to cut off
FINE_TUNING_FREQ_INCREMENT = 1; % [bpm] Separation between test tones for smoothing
fps = 20; % frame per second
i = 1;
y = [];
%first loop, get 5 seconds of data
while(size(y,2) ~= 100)
cam = imread(url); % read source
pic(:,:,i) = cam(:, :, 1); % take RED domain only
y(i) = sum(sum(pic(:,:,i))) / (size(cam, 1) * size(cam, 2));
i = i + 1
disp('Collecting data...');
end
% butterworth filter
[b, a] = butter(2, [(((BPM_L)/60)/fps*2) (((BPM_H)/60)/fps*2)]);
% 5-points moving average for smoothing
yfilt = filter(b, a, y);
% cuts the first second and takes the remaing for seconds of data
% The first second is the filter transient
y = yfilt((fps * max(FILTER_STABILIZATION_TIME, CUT_START_SECONDS))+1:size(yfilt, 2));
% Some initializations and precalculations
fcl = BPM_L / 60;
fch = BPM_H / 60;
bpm = [];
bpm_smooth = [];
% second loop
% step 1) make calculations on the first 4 seconds of data
% step 2) take the last 3 seconds
% step 3) add 20 new frames, that makes the array 4 seconds long again
% step 4) goto step 1)
while(1)
if(i==101)
% *********************** STEP 1 ***********************
for j=1:size(y,2)
gain = abs(fft(y));
il = floor(fcl * (size(y, 2) / fps))+1;
ih = ceil(fch * (size(y, 2) / fps))+1;
index_range = il:ih;
[pks, locs] = findpeaks(gain(index_range));
[max_peak_v, max_peak_i] = max(pks);
max_f_index = index_range(locs(max_peak_i));
bpm(j) = (max_f_index-1) * (fps / size(y, 2)) * 60;
freq_resolution = 1 / WINDOW_SECONDS;
lowf = bpm(j) / 60 - 0.5 * freq_resolution;
freq_inc = FINE_TUNING_FREQ_INCREMENT / 60;
test_freqs = round(freq_resolution / freq_inc);
power = zeros(1, test_freqs);
freqs = (0:test_freqs-1) * freq_inc + lowf;
for h = 1:test_freqs,
re = 0; im = 0;
for k = 0:(size(y, 2) - 1),
phi = 2 * pi * freqs(h) * (j / fps);
re = re + y(k+1) * cos(phi);
im = im + y(k+1) * sin(phi);
end
power(h) = re * re + im * im;
end
[max_peak_v, max_peak_i] = max(power);
bpm_smooth(j) = 60*freqs(max_peak_i);
% ******************************************************
end
disp(['Mean HR: ' num2str(mean(bpm_smooth)) ' bpm']);
disp('.');
% *** STEP 2 ***
y = y(20:80);
i = 60;
% **************
end
% ************************ STEP 3 ***************************
i = i + 1;
cam = imread(url);
pic(:,:,i) = cam(:, :, 1); % take RED domain only
y(i) = sum(sum(pic(:,:,i))) / (size(cam, 1) * size(cam, 2));
% ***********************************************************
end
pastebin version for nicer view http://pastebin.com/tYq7D4mp
This code does the following:
  • read frames from webcam source (20 / sec)
  • calculate BPM
  • do it again in a neverending loop always with the new data that comes meantime
It does not work like I wanted.. first sec 105bpm, next second 60. It fluctuates badly. How should I correct it?

回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Matched Filter and Ambiguity Function 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by