Euclidean distance between each pixel of an image and pixels with spesific color

7 views (last 30 days)
How can i find the normalised euclidean distance between each pixel of an image and pixels with spesific color(for example bluegray ) ? I attach a matlab code which creates a mask to skin lesion , then convert image from RGB colorspace to lab color space and finally creates the Delta E image. The problem is that i dont know how to continue in order to find the distance between each pixel of the lesion and a spesific color. My purpose is to find the percentage of appearence of a specific color in the mask of the image. Could anyone please help me?

Accepted Answer

Image Analyst
Image Analyst on 26 Sep 2022
I've fixed up the code so try this:
% Initialization Steps.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 18;
markerSize = 40;
fprintf('Beginning to run %s.m ...\n', mfilename);
%-----------------------------------------------------------------------------------------------------------------------------------
% Read in image.
folder = [];
baseFileName = 'color.jpg';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~isfile(fullFileName)
% 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
fullFileName = fullFileNameOnSearchPath;
end
rgbImage = imread(fullFileName);
[rows, columns, numberOfColorChannels] = size(rgbImage)
numberOfPixels = rows*columns;
% Display the image.
subplot(2, 3, 1);
imshow(rgbImage, []);
axis('on', 'image');
caption = sprintf('RGB Image : "%s"', baseFileName);
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');
%-----------------------------------------------------------------------------------------------------------------------------------
% Segment (mask) the image.
[mask, maskedRGBImage] = createMask(rgbImage);
% Take largest blob only.
mask = bwareafilt(mask, 1);
% Fill any possible holes.
mask = imfill(mask, 'holes');
% Get masked image again with new mask
% Mask image by multiplying each channel by the mask.
maskedRgbImage = rgbImage .* cast(mask, 'like', rgbImage);
subplot(2, 3, 2);
imshow(mask, []);
axis('on', 'image');
title('Skin Lesion Mask', 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
subplot(2, 3, 3);
imshow(maskedRgbImage, []);
axis('on', 'image');
title('Masked Image', 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
% Get the boundary of the mask
lesionBoundary = bwboundaries(mask);
%-----------------------------------------------------------------------------------------------------------------------------------
% CONVERT IMAGE TO CIE LAB USING "BOOK FORMULAS" (UNCALIBRATED!).
lab_Image = rgb2lab(rgbImage);
% Extract out the color bands from the original image
% into 3 separate 2D arrays, one for each color component.
[lImage, aImage, bImage] = imsplit(lab_Image);
% Display the lab images.
subplot(2, 3, 4);
imshow(lImage, []);
impixelinfo;
hold on;
visboundaries(lesionBoundary);
hold off;
title('L Channel', 'FontSize', fontSize);
subplot(2, 3, 5);
imshow(aImage, []);
impixelinfo;
hold on;
visboundaries(lesionBoundary);
hold off;
title('a Channel', 'FontSize', fontSize);
subplot(2, 3, 6);
imshow(bImage, []);
impixelinfo;
hold on;
visboundaries(lesionBoundary);
hold off;
title('b Channel', 'FontSize', fontSize);
% Get the average lab color value.
[LMean, aMean, bMean] = GetMeanLABValues(lImage, aImage, bImage, mask);
%-----------------------------------------------------------------------------------------------------------------------------------
% DEFINE REFERENCE COLORS.
% VERY VERY IMPORTANT: NEED TO BE EITHER UINT8 IF IN THE RANGE 0-255 OR
% NEED TO BE IN THE RANGE 0-1 IF THE TYPE IS DOUBLE.
bluegray = uint8([0 134 139]);
white= uint8([255 255 255]);
black = uint8([0 0 0]);
red = uint8([255 0 0]);
darkbrown = uint8([101 67 33]);
lightbrown = uint8([205 133 63]);
% Convert reference colors from RGB colorspace to lab color space.
refLab_bg = rgb2lab(bluegray)
refLab_wh = rgb2lab(white)
refLab_bl = rgb2lab(black)
refLab_red = rgb2lab(red)
refLab_db = rgb2lab(darkbrown)
refLab_lbr = rgb2lab(lightbrown)
%-----------------------------------------------------------------------------------------------------------------------------------
% Make new figure to hold original images and delta E images.
hFigDE = figure;
subplot(3, 3, 1);
imshow(rgbImage, []);
impixelinfo
title('Original Image', 'FontSize',fontSize)
drawnow;
%-----------------------------------------------------------------------------------------------------------------------------------
% Create the Delta E image for blue gray.
% This is an image that represents the color difference.
deImage_bg = GetDeltaEImage(lImage, aImage, bImage, refLab_bg);
subplot(3, 3, 2);
imshow(deImage_bg, []);
impixelinfo;
hold on;
visboundaries(lesionBoundary);
hold off;
title('Delta E Blue Gray', 'FontSize',fontSize)
drawnow;
%-----------------------------------------------------------------------------------------------------------------------------------
% Compute the Delta E image for white color.
deImage_wh = GetDeltaEImage(lImage, aImage, bImage, refLab_wh);
subplot(3, 3, 3);
imshow(deImage_wh, []);
impixelinfo;
hold on;
visboundaries(lesionBoundary);
hold off;
title('Delta E White', 'FontSize',fontSize)
drawnow;
%-----------------------------------------------------------------------------------------------------------------------------------
% Create the Delta E image for blue gray.
% This is an image that represents the color difference.
deImage_bl = GetDeltaEImage(lImage, aImage, bImage, refLab_bl);
subplot(3, 3, 4);
imshow(deImage_bl, []);
impixelinfo;
hold on;
visboundaries(lesionBoundary);
hold off;
title('Delta E Black', 'FontSize',fontSize)
%-----------------------------------------------------------------------------------------------------------------------------------
% Create the Delta E image for red.
% This is an image that represents the color difference.
deImage_red = GetDeltaEImage(lImage, aImage, bImage, refLab_red);
subplot(3, 3, 5);
imshow(deImage_red, []);
impixelinfo;
hold on;
visboundaries(lesionBoundary);
hold off;
title('Delta E Red', 'FontSize',fontSize)
drawnow;
%-----------------------------------------------------------------------------------------------------------------------------------
% Create the Delta E image for dark brown.
% This is an image that represents the color difference.
deImage_db = GetDeltaEImage(lImage, aImage, bImage, refLab_db);
subplot(3, 3, 6);
imshow(deImage_db, []);
impixelinfo;
hold on;
visboundaries(lesionBoundary);
hold off;
title('Delta E Dark Brown', 'FontSize',fontSize)
drawnow;
%-----------------------------------------------------------------------------------------------------------------------------------
% Create the Delta E image for light brown.
% This is an image that represents the color difference.
deImage_lbr = GetDeltaEImage(lImage, aImage, bImage, refLab_lbr);
subplot(3, 3, 7);
imshow(deImage_lbr, []);
impixelinfo;
hold on;
visboundaries(lesionBoundary);
hold off;
title('Delta E Light Brown', 'FontSize',fontSize)
drawnow;
hFigDE.WindowState = "maximized";
%-----------------------------------------------------------------------------------------------------------------------------------
% Get mean Delta E color difference just within the mask area ONLY:
meanDE_bg = mean(deImage_bg(mask))
meanDE_wh = mean(deImage_wh(mask))
meanDE_bl = mean(deImage_bl(mask))
meanDE_rd = mean(deImage_red(mask))
meanDE_db = mean(deImage_db(mask))
meanDE_lbr = mean(deImage_lbr(mask))
%==============================================================================================================================
function deImage = GetDeltaEImage(lImage, aImage, bImage, refLAB)
try
deImage = sqrt((lImage - refLAB(1)).^2 + (aImage - refLAB(2)).^2 + (bImage - refLAB(3)).^2);
catch ME
errorMessage = sprintf('Error running GetDeltaEImage:\n\n\nThe error message is:\n%s', ...
ME.message);
WarnUser(errorMessage);
end
end
%==============================================================================================================================
% Get the average lab within the mask region.
function [LMean, aMean, bMean] = GetMeanLABValues(LChannel, aChannel, bChannel, mask)
try
LVector = LChannel(mask); % 1D vector of only the pixels within the masked area.
LMean = mean(LVector);
aVector = aChannel(mask); % 1D vector of only the pixels within the masked area.
aMean = mean(aVector);
bVector = bChannel(mask); % 1D vector of only the pixels within the masked area.
bMean = mean(bVector);
catch ME
errorMessage = sprintf('Error running GetMeanLABValues:\n\n\nThe error message is:\n%s', ...
ME.message);
WarnUser(errorMessage);
end
return; % from GetMeanLABValues
end
%==============================================================================================================================
function WarnUser(message)
fprintf('%s\n', message)
uiwait(warndlg(message))
end
%==============================================================================================================================
% Get mask of melanoma.
function [BW,maskedRGBImage] = createMask(RGB)
%createMask Threshold RGB image using auto-generated code from colorThresholder app.
% [BW,MASKEDRGBIMAGE] = createMask(RGB) thresholds image RGB using
% auto-generated code from the colorThresholder app. The colorspace and
% range for each channel of the colorspace were set within the app. The
% segmentation mask is returned in BW, and a composite of the mask and
% original RGB images is returned in maskedRGBImage.
% Auto-generated by colorThresholder app on 22-Sep-2022
%------------------------------------------------------
% Convert RGB image to chosen color space
I = rgb2hsv(RGB);
% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.000;
channel1Max = 1.000;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 0.000;
channel2Max = 1.000;
% Define thresholds for channel 3 based on histogram settings
channel3Min = 0.000;
channel3Max = 0.544;
% Create mask based on chosen histogram thresholds
sliderBW = (I(:,:,1) >= channel1Min ) & (I(:,:,1) <= channel1Max) & ...
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) & ...
(I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
BW = sliderBW;
% Initialize output masked image based on input image.
maskedRGBImage = RGB;
% Set background pixels where BW is false to zero.
maskedRGBImage(repmat(~BW,[1 1 3])) = 0;
end
  5 Comments
Image Analyst
Image Analyst on 28 Sep 2022
You will not find delta e's less than 0.4, or at least very many of them.
You can stack the 6 delta e images up into a 3-D array with cat(3,...) then use max along the third dimension to find out what color each pixel was closest to, in essense creating a classified image. You can take the histogram of the classified image to find out the relative proportions of each color in your lesion mask.
JovanS
JovanS on 7 Oct 2022
@Image Analyst hello again, i have a question . How can I do this ? I want to find for every pixel in the lesion the color(between 6 colors) was closest to.In order to find this i have to compare every pixel with euclidean distance of each color and i guess that the pixel will be closest to the color which euclidean distance is shortest. I dont know how to do this . It would be very helpful for me to answer!

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 24 Sep 2022
I didn't look at your code but the solution to what you asked is very easy. I'll assume you have a reference color "bluegray" and a rgb image, and a mask, you can do this
% Convert both to LAB color space
labImage = rgb2lab(rgbImage);
[lImage, aImage, bImage] = imsplit(labImage);
refLab = rgb2lab(bluegray)
% Compute the Delta E image.
deImage = sqrt((lImage - refLab(1)).^2 + (aImage - refLab(2)).^2 + (bImage - refLab(3)).^2);
imshow(deImage, []);
impixelinfo % Can mouse around over image and see the Delta E value.
% That gives the delta E at every single pixel location in the image.
% If you want the mean Delta E color difference just within the mask area you can do
meanDE = mean(deImage(mask))
  2 Comments
JovanS
JovanS on 26 Sep 2022
Thank you for your respone , I follow your instructions but I am not sure if the results that I get are right. I have to point out that I want the Euclidean distance between the refernce color and the pixels of the inner part of lesion's mask. To be clear my purpose is to scan all the pixels constituting the lesion(mask) (i.e. excludingsurrounding healthy skin). Could you please check my code ? I would really appreciate it if you could help me . As you will see i have 6 different reference colors so i have done the same procedure 6 times. the image is the same that i attached before. @Image Analyst
Image Analyst
Image Analyst on 26 Sep 2022
The code is a mess. Looks like you've tried to blend two separate programs without really understanding what's going on. I'll try to fix it up today as I get time.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!