Skin detection code problem?

10 views (last 30 days)
Shravanthi
Shravanthi on 30 Apr 2014
Commented: Mustapha Seidu on 15 Sep 2021
Is something wrong with my skin detection code? No matter what I try, I can't seem to get a bounding box around the hand region, it always encompasses the whole picture. I've included the code and the pictures I get.
I've used Image Analyst's ExtractNLargestBlobs() for getting the largest blob, which is the hand region. I'd really appreciate it if somebody can tell me what's wrong with the code!
Thank you!
clc;
clear all;
currentimg=imread('palm.jpg'); %capture the image of interest
%Read the image, and capture the dimensions
VidImage = currentimg;
height = size(VidImage,1);
width = size(VidImage,2);
%Initialize the output images
out = VidImage;
bin = zeros(height,width);
%Convert the image from RGB to YCbCr
img_ycbcr = rgb2ycbcr(VidImage);
Cb = img_ycbcr(:,:,2);
Cr = img_ycbcr(:,:,3);
%Detect Skin
[r,c,v] = find(Cb>=77 & Cb<=127 & Cr>=133 & Cr<=173);
numind = size(r,1);
%Mark Skin Pixels
for i=1:numind
out(r(i),c(i),:) = [0 0 255];
bin(r(i),c(i)) = 1;
end
binaryImage=im2bw(bin,graythresh(bin));
binaryImage=~binaryImage;
B = bwboundaries(binaryImage);
% imshow(binaryImage)
binaryImage = imfill(binaryImage, 'holes');
% Remove tiny regions.
binaryImage = bwareaopen(binaryImage, 5000);
%---------------------------------------------------------------------------
% Extract the largest area using ImageAnalyst's custom function ExtractNLargestBlobs().
biggestBlob = ExtractNLargestBlobs(binaryImage, 1);
% Display the image.
imshow(biggestBlob, []);
title('Final Image');
%--------------------------------------------------------------------------
[labeledImage, numberOfBlobs] = bwlabel(biggestBlob, 8);
% Get all the blob properties.
blobMeasurements = regionprops(labeledImage, 'BoundingBox','Area');
allBlobAreas = [blobMeasurements.Area];
% Display the original gray scale image.
imshow(currentimg, []);
% Loop through all blobs, putting up Bounding Box.
hold on; % Prevent boxes from blowing away the image and prior boxes.
for k = 1 : numberOfBlobs
boundingBox = blobMeasurements(k).BoundingBox; % Get box.
x1 = boundingBox(1);
y1 = boundingBox(2);
x2 = x1 + boundingBox(3) - 1;
y2 = y1 + boundingBox(4) - 1;
verticesX = [x1 x2 x2 x1 x1];
verticesY = [y1 y1 y2 y2 y1];
plot(verticesX, verticesY);
end

Accepted Answer

Image Analyst
Image Analyst on 1 May 2014
You inverted the binary image when you shouldn't have. You need to have the hand be the foreground (white). Try this fixed code, after changing the filename to what you have on your computer:
clc;
workspace
fontSize = 20;
folder = 'C:\Users\shravnathi\Documents\Temporary';
baseFileName = 'origpalm.png';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
currentimg=imread(fullFileName); %capture the image of interest
subplot(2,2,1);
imshow(currentimg);
title('Original Image', 'FontSize', fontSize);
%Read the image, and capture the dimensions
VidImage = currentimg;
height = size(VidImage,1);
width = size(VidImage,2);
%Initialize the output images
out = VidImage;
bin = zeros(height,width);
%Convert the image from RGB to YCbCr
img_ycbcr = rgb2ycbcr(VidImage);
Cb = img_ycbcr(:,:,2);
Cr = img_ycbcr(:,:,3);
%Detect Skin
[r,c,v] = find(Cb>=77 & Cb<=127 & Cr>=133 & Cr<=173);
numind = size(r,1);
%Mark Skin Pixels
for i=1:numind
out(r(i),c(i),:) = [0 0 255];
bin(r(i),c(i)) = 1;
end
binaryImage=im2bw(bin,graythresh(bin));
% binaryImage=~binaryImage;
subplot(2,2,2);
imshow(binaryImage);
title('Binary Image', 'FontSize', fontSize);
B = bwboundaries(binaryImage);
% imshow(binaryImage)
binaryImage = imfill(binaryImage, 'holes');
% Remove tiny regions.
binaryImage = bwareaopen(binaryImage, 5000);
subplot(2,2,3);
imshow(binaryImage);
title('Second Binary Image', 'FontSize', fontSize);
%---------------------------------------------------------------------------
% Extract the largest area using ImageAnalyst's custom function ExtractNLargestBlobs().
biggestBlob = ExtractNLargestBlobs(binaryImage, 1);
% Display the image.
subplot(2,2, 4);
imshow(biggestBlob);
title('Final Image', 'FontSize', fontSize);
%--------------------------------------------------------------------------
[labeledImage, numberOfBlobs] = bwlabel(biggestBlob, 8);
% Get all the blob properties.
blobMeasurements = regionprops(labeledImage, 'BoundingBox','Area');
allBlobAreas = [blobMeasurements.Area];
% Display the original gray scale image.
subplot(2,2,1);
% Loop through all blobs, putting up Bounding Box.
hold on; % Prevent boxes from blowing away the image and prior boxes.
for k = 1 : numberOfBlobs
boundingBox = blobMeasurements(k).BoundingBox; % Get box.
x1 = boundingBox(1);
y1 = boundingBox(2);
x2 = x1 + boundingBox(3) - 1;
y2 = y1 + boundingBox(4) - 1;
verticesX = [x1 x2 x2 x1 x1];
verticesY = [y1 y1 y2 y2 y1];
plot(verticesX, verticesY, 'r-', 'LineWidth', 2);
end
uiwait(msgbox('Done with demo'));
  6 Comments
Image Analyst
Image Analyst on 14 Sep 2021
@LEELA SURYA TEJA MANGAMURI, instead of extractNLargestBlobs(), you can now use the built-in bwareafilt().
@Mustapha Seidu, no need to modify anything. The code already extracts all blob measurements automatically with this line of code:
blobMeasurements = regionprops(labeledImage, 'BoundingBox','Area');

Sign in to comment.

More Answers (2)

komal
komal on 30 May 2019
code
clc;
workspace
fontSize = 20;
folder = 'C:\Users\Dell\Documents\MATLAB';
baseFileName = 'frame129.jpg';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
currentimg=imread(fullFileName); %capture the image of interest
subplot(2,2,1);
imshow(currentimg);
title('Original Image', 'FontSize', fontSize);
%Read the image, and capture the dimensions
VidImage = currentimg;
height = size(VidImage,1);
width = size(VidImage,2);
%Initialize the output images
out = VidImage;
bin = zeros(height,width);
%Convert the image from RGB to YCbCr
img_ycbcr = rgb2ycbcr(VidImage);
Cb = img_ycbcr(:,:,2);
Cr = img_ycbcr(:,:,3);
%Detect Skin
[r,c,v] = find(Cb>=77 & Cb<=127 & Cr>=133 & Cr<=173);
numind = size(r,1);
%Mark Skin Pixels
for i=1:numind
out(r(i),c(i),:) = [0 0 255];
bin(r(i),c(i)) = 1;
end
binaryImage=im2bw(bin,graythresh(bin));
% binaryImage=~binaryImage;
binaryImage = imfill(binaryImage, 'holes');
% Remove tiny regions.
binaryImage = bwareaopen(binaryImage, 5000);
subplot(2,2,3);
imshow(binaryImage);
title('Second Binary Image', 'FontSize', fontSize);
%---------------------------------------------------------------------------
% Extract the largest area using ImageAnalyst's custom function ExtractNLargestBlobs().
biggestBlob = ExtractNLargestBlobs(binaryImage, 1);
% Display the image.
subplot(2, 2, 4);
imshow(biggestBlob, []);
title('Final Image', 'FontSize', fontSize);
%--------------------------------------------------------------------------
[labeledImage, numberOfBlobs] = bwlabel(biggestBlob, 8);
% Get all the blob properties.
blobMeasurements = regionprops(labeledImage, 'BoundingBox','Area');
allBlobAreas = [blobMeasurements.Area];
% Display the original gray scale image.
subplot(2,2,1);
% Loop through all blobs, putting up Bounding Box.
hold on; % Prevent boxes from blowing away the image and prior boxes.
for k = 1 : numberOfBlobs
boundingBox = blobMeasurements(k).BoundingBox; % Get box.
x1 = boundingBox(1);
y1 = boundingBox(2);
x2 = x1 + boundingBox(3) - 1;
y2 = y1 + boundingBox(4) - 1;
verticesX = [x1 x2 x2 x1 x1];
verticesY = [y1 y1 y2 y2 y1];
plot(verticesX, verticesY, 'r-', 'LineWidth', 2);
end
uiwait(msgbox('Done with demo'));
it shows error in " biggestBlob = ExtractNLargestBlobs(binaryImage, 1);". Please help me to correct it
I have also attached the image and it is blur because I have taken image by extracting from the video.
  3 Comments
komal
komal on 11 Jun 2019
Try this
code:
function binaryImage = ExtractNLargestBlobs(binaryImage, numberToExtract)
try
% Get all the blob properties. Can only pass in originalImage in version R2008a and later.
[labeledImage, numberOfBlobs] = bwlabel(binaryImage);
blobMeasurements = regionprops(labeledImage, 'area');
% Get all the areas
allAreas = [blobMeasurements.Area];
if numberToExtract > 0
% For positive numbers, sort in order of largest to smallest.
% Sort them.
[sortedAreas, sortIndexes] = sort(allAreas, 'descend');
elseif numberToExtract < 0
% For negative numbers, sort in order of smallest to largest.
% Sort them.
[sortedAreas, sortIndexes] = sort(allAreas, 'ascend');
% Need to negate numberToExtract so we can use it in sortIndexes later.
numberToExtract = -numberToExtract;
else
% numberToExtract = 0. Shouldn't happen. Return no blobs.
binaryImage = false(size(binaryImage));
return;
end
% Extract the "numberToExtract" largest blob(a)s using ismember().
biggestBlob = ismember(labeledImage, sortIndexes(1:numberToExtract));
% Convert from integer labeled image into binary (logical) image.
binaryImage = biggestBlob > 0;
catch ME
errorMessage = sprintf('Error in function ExtractNLargestBlobs().\n\nError Message:\n%s', ME.message);
fprintf(1, '%s\n', errorMessage);
uiwait(warndlg(errorMessage));
end
Image Analyst
Image Analyst on 11 Jun 2019
This is not needed anymore. There is now a function in the Image Processing Toolbox called bwareafilt() that does this:
biggestBlob = bwareafilt(binaryImage, 1); % Extract largest blob ONLY.

Sign in to comment.


Ashwini Selokar
Ashwini Selokar on 23 Feb 2021
skin diseases detection using mathlab coding
  1 Comment
Image Analyst
Image Analyst on 23 Feb 2021
This is not an answer to @Shravanthi. I suggest you search this forum, the File Exchange, and VisonBibliography for some algorithms that you can code up or buy, or people who you can hire to do it for you if you don't want to write it yourself.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!