images_to_heartpulses/V2rgb.m

141 lines
3.4 KiB
Matlab

%%%%%%%%%%%%%%%%%
%
%
% Task: Detect heart rate through video
%
%
%
% Authord: Estevan Biau-Loyer & Darren Gallois
% Date: 19/02/2023
%
%%%%%%%%%%%%%%%%%
% Loop through the images selected
% Initialize a matrix to store RGB values
all_rgb = zeros(900, 3, 61, 101);
% Initialize iteration
a=0;
for i = 100:1000
% Set the image path
image_path = imread(sprintf('frame2_%d.jpg', i));
[rows, columns, channels] = size(image_path);
%Create the ROI
roi = image_path(90:150, 300:400, :);
% Save the images adjusted to the ROI
imwrite(roi, (sprintf('frames/my_imagev2%d.jpg',i)));
end
% Loop through 900 images
for i = 100:1000
% Read image
img = imread(sprintf('frames/my_imagev2%d.jpg', i));
% Convert to double precision
img = im2double(img);
% Separate RGB channels
red = img(:,:,1);
green = img(:,:,2);
blue = img(:,:,3);
% Store RGB channels in the matrix
all_rgb(i, 1, :, :) = red;
all_rgb(i, 2, :, :) = green;
all_rgb(i, 3, :, :) = blue;
a=a+1;
% Display iteration
disp(a);
end
% Compute mean RGB values for each image
mean_rgb = squeeze(mean(mean(all_rgb, 4), 3));
save('mean_rgb.m', 'mean_rgb');
% Load the mean RGB values from the .m file
load('mean_rgb.m');
% Get the number of images
num_images = size(mean_rgb, 1);
% Create a vector of indices for each image
indices = 1:num_images;
% Plot the green channel
figure;
plot(indices, mean_rgb(:, 1), 'r');
hold on;
% Plot the red channel
plot(indices, mean_rgb(:, 2), 'g');
% Plot the blue channel
plot(indices, mean_rgb(:, 3), 'b');
% Add legend and labels
legend({'Red', 'Green', 'Blue'});
xlabel('Image index');
ylabel('Mean RGB value');
% Get the standard deviation of each color
red_std = std(mean_rgb(:, 1));
green_std = std(mean_rgb(:, 2));
blue_std = std(mean_rgb(:, 3));
% Get the average value of each color
red_avg = mean(mean_rgb(:, 1));
green_avg = mean(mean_rgb(:, 2));
blue_avg = mean(mean_rgb(:, 3));
% Normalize the values
red_normalized = (mean_rgb(:, 1) - red_avg)/red_std
green_normalized = (mean_rgb(:, 2) - green_avg)/green_std
blue_normalized = (mean_rgb(:, 3) - blue_avg)/blue_std
% Create the 3 channels fft
red_fft = fft(red_normalized)
green_fft = fft(green_normalized)
blue_fft = fft(blue_normalized)
N = length(red_normalized); % length of the signal
freq = fftshift(fftfreq(N)); % frequency vector in Hz
% plot the FFT result for the three channels
figure;
hold on;
plot(freq, abs(red_fft));
plot(freq, abs(green_fft));
plot(freq, abs(blue_fft));
hold off;
xlabel('Frequency (Hz)');
ylabel('Magnitude');
legend({'Red', 'Green', 'Blue'});
% Find indices in f that correspond to the frequency range of interest
idx_range = find(f >= 0.75 & f <= 4);
% Extract the amplitude values in the range of interest for each channel
red_amp_range = abs(red_fft(idx_range));
green_amp_range = abs(green_fft(idx_range));
blue_amp_range = abs(blue_fft(idx_range));
% Find the index of the maximum amplitude value in the range of interest for each channel
[red_max_amp, red_max_idx] = max(red_amp_range);
[green_max_amp, green_max_idx] = max(green_amp_range);
[blue_max_amp, blue_max_idx] = max(blue_amp_range);
% Convert index of maximum amplitude value to frequency, and then to bpm
red_bpm = f(idx_range(red_max_idx)) * 60;
green_bpm = f(idx_range(green_max_idx)) * 60;
blue_bpm = f(idx_range(blue_max_idx)) * 60;
% Determine heart rate by taking the average of the bpm values for the three channels
heart_rate = mean([red_bpm, green_bpm, blue_bpm]);
disp(heart_rate);