Clear Filters
Clear Filters

how to separate the wave from ecg image

7 views (last 30 days)
Attachment is original color image of ECG in png version.
The task is to separate the wave from the rest (removing red dots, black column and row bars, the little black rectangle over the peak of wave).
Ang way to do that? Following is a portion of the ECG image

Accepted Answer

Image Analyst
Image Analyst on 15 Feb 2022
Try this:
% Demo by Image Analyst to extract an ECG signal from an image or a paper strip chart.
% Feb. 15, 2022
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clearvars;
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 16;
fprintf('Beginning to run %s.m ...\n', mfilename);
%-----------------------------------------------------------------------------------------------------------------------------------
% Read in image.
folder = pwd;
baseFileName = 'ecg.png';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbImage = imread(fullFileName);
[rows, columns, numberOfColorChannels] = size(rgbImage)
% Display the image.
subplot(3, 2, 1);
imshow(rgbImage, []);
axis('on', 'image');
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
caption = sprintf('Original RGB Image : "%s"\n%d rows by %d columns', baseFileName, rows, columns);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Set up figure properties:
% Enlarge figure to full screen.
hFig1 = gcf;
hFig1.Units = 'Normalized';
hFig1.WindowState = 'maximized';
% Get rid of tool bar and pulldown menus that are along top of figure.
% set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
hFig1.Name = 'Demo by Image Analyst';
%-----------------------------------------------------------------------------------------------------------------------------------
% Get the red channel and threshold it at 107.
mask = rgbImage(:, :, 1) < 107;
% Display the image.
subplot(3, 2, 2);
imshow(mask, []);
axis('on', 'image');
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
caption = sprintf('Binary Mask Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
% Find the vertical axis by summing vertically
horizontalProfile = sum(mask, 1);
% Display the image.
subplot(3, 2, 3);
plot(horizontalProfile, 'b-', 'LineWidth', 2)
grid on;
caption = sprintf('Mask Summed Vertically');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
% Find out which columns have more than 100 pixels in them and erase those from the mask.
badColumns = horizontalProfile > 100;
mask(:, badColumns) = false;
% Now take the largest blob.
mask = bwareafilt(mask, 1);
% Now skeletonize down to a single pixel wide line.
mask = bwskel(mask);
% Display the image.
subplot(3, 2, 4);
imshow(mask, []);
axis('on', 'image');
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
caption = sprintf('Final Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
% Get the signal
signal = nan(1, columns);
for col = 1 : columns
t = find(mask(:, col), 1, "first");
if ~isempty(t)
signal(col) = rows - t;
end
end
% Get rid of any nans
badIndexes = isnan(signal);
x = 1 : columns; % Initialize to entire width.
x(badIndexes) = []; % Remove nans
signal(badIndexes) = [];
% Now we can rescale the signal from units of rows to whatever we want, like to the 0-1 range.
signal = rescale(signal, 0, 1);
% Now plot the final signal.
subplot(3, 2, 5:6);
plot(x, signal, 'b-', 'LineWidth', 3);
grid on;
title('Final Signal', 'FontSize', fontSize);
xlabel('Column', 'FontSize', fontSize);
ylabel('Row', 'FontSize', fontSize);
  10 Comments
Image Analyst
Image Analyst on 19 Feb 2022
By looking at the vertical profile you can find out where the signal is lowest, which is where those solid black lines go all the way across the image. If you can't do it that way, just divide it evenly using startRows and endRows.
lt c
lt c on 19 Feb 2022
Quite right. And the number of strips equals to the number of solid black lines minus 1.
Thank you. It is great to have you in this community. I have accepted your answer.
Hope I could learn more from you.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!