real time smartphone camera processing v2

1 Ansicht (letzte 30 Tage)
Abel
Abel am 26 Nov. 2014
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?

Antworten (0)

Community Treasure Hunt

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

Start Hunting!

Translated by