Can any one correct this code to remove hair pixels??

Hi!! Can any on help to remove pixels hair from a dermoscopic image with DullRazor method. DullRazor performs the following steps: -It identifies the dark hair locations by a generalized grayscale morphological closing operation, -It verifies the shape of the hair pixels as thin and long structure, and replace the verified pixels by a bilinear interpolation, and -It smooths the replaced hair pixels with an adaptive median filter. I tried this but it's not correct:
image = im2double(imread('image1.bmp'));
figure, imshow(image);
grayscale = rgb2gray(image);
%get hairs using bottomhat filter
se = strel('disk',5);
hairs = imbothat(grayscale,se);
figure, imshow(hairs);

Answers (1)

You need to find the hairs first. Binarize (threshold) and then use regionprops to identify long thin objects. Then use roifill() to replace those objects with the surrounding neighborhood background. I'm not sure what the median filter would gain you - I don't think it's necessary.

15 Comments

Thanks I tried to correct the code using your advice
image = im2double(imread('image.bmp'));
figure(1), imshow(image);
grayscale = rgb2gray(image);
se = strel('disk',5);
hairs = imbothat(grayscale,se);
figure(2), imshow(hairs);
mask = bwlabel(hairs);
figure(3), imshow(mask);
stats = regionprops(mask, 'MajorAxisLength', 'MinorAxisLength');
major = stats.MajorAxisLength
minor = stats.MinorAxisLength
image2 = roifill(image,mask);
figure(5), imshow(image2);
But i can't understand how can i use the variable major and minor?? i have also an error widh roifill
??? Error using ==> iptcheckinput
Function ROIFILL expected its first input, I, to be two-dimensional.
You need to do it on a grayscale image, or each channel of the color image one at a time.
How can i use the variable major and minor because the result is insufficient.
image = im2double(imread('image.bmp'));
figure(1), imshow(image);
grayscale = rgb2gray(image);
se = strel('disk',5);
hairs = imbothat(grayscale,se);
figure(2), imshow(hairs);
mask = bwlabel(hairs);
figure(3), imshow(mask);
stats = regionprops(mask, 'MajorAxisLength', 'MinorAxisLength');
major = stats.MajorAxisLength
minor = stats.MinorAxisLength
image2 = roifill(grayscale,mask);
figure(5), imshow(image2);
You can't, because you don't have separated hairs. They're all overlapping and crossing. You can try the code below. It's not perfect but ti gives you someplace to start.
% Demo to eliminate hairs.
% By ImageAnalyst
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
fontSize = 14;
% Read in a standard MATLAB gray scale demo image.
folder = 'C:\Users\Mark\Documents\Temporary';
baseFileName = 'DullRazor.jpg';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
% Didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbImage = imread(fullFileName);
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows columns numberOfColorBands] = size(rgbImage);
% Display the original color image.
subplot(2, 2, 1);
imshow(rgbImage, []);
% See if we can get rid of the hairs in the RGB image.
% rgbImage = imerode(rgbImage, true(5));
title('Original Color Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
% Display the original color image.
subplot(2, 2, 2);
imshow(redChannel, []);
title('Red Channel', 'FontSize', fontSize);
subplot(2, 2, 3);
imshow(greenChannel, []);
title('Green Channel', 'FontSize', fontSize);
subplot(2, 2, 4);
imshow(blueChannel, []);
title('Blue Channel', 'FontSize', fontSize);
figure;
% Let's compute and display the histogram.
[pixelCount grayLevels] = imhist(redChannel);
subplot(2, 2, 1);
bar(pixelCount);
grid on;
title('Histogram of red Channel', 'FontSize', fontSize);
xlim([0 grayLevels(end)]); % Scale x axis manually.
% Threshold the image
binaryImage = redChannel < 120;
binaryImage = imdilate(binaryImage, true(5));
% Display it.
subplot(2, 2, 2);
imshow(binaryImage, []);
title('Binary Image', 'FontSize', fontSize);
% Fill in the mask
redChannel = roifill(redChannel, binaryImage);
greenChannel = roifill(greenChannel, binaryImage);
blueChannel = roifill(blueChannel, binaryImage);
noHairImage = cat(3, redChannel, greenChannel, blueChannel);
% Display it.
subplot(2, 2, 3);
imshow(noHairImage, []);
title('No Hair Image', 'FontSize', fontSize);
Pamela
Pamela on 8 Sep 2012
Edited: Pamela on 8 Sep 2012
thank you for this code, it will help me a lot, but unfortunately I should use the DullRazor method mentioned above
Well you can do a median filter and subtract it from your original images to get the hairs, or do a bottom hat filter (a morphological way of doing a similar thing). But you don't have isolated straight short hair segments so the part of DullRazor that assumes that won't work. It just won't. You don't have the kind of image it was meant for. What I would suggest for a work around is to calculate the Euclidean Distance transform with bwdist() and then threshold that to find values less than the radius of the thickest hair, say 2 or 3 pixels. Then use that as a mask. This will avoid using most of the big dark areas as part of the mask, like that big dark pigmented area in your photo - it will use only narrow areas like hairs and only the outer 2 or 3 pixels of the big dark blobs.
Hi Image Analyst,
please Could write your last suggestion for Pamela to remove hair pixels in MATLAB code. thanks in advance
Hamed
medianFiltered = medfilt2(grayImage, [9,9]);
subtraction = double(grayImage) - double(medianFiltered);
Image Analyst, Thank you very much, I wrote this code but I did not get good result please could guide me where I am new in MATLAB
% Dull Razor algorithm
% 1-It identifies the dark hair locations by a generalized grayscale morphological closing operation,
% % 2-It verifies the shape of the hair pixels as thin and long structure, and replace the verified pixels by a bilinear interpolation, and
% % 3-It smooths the replaced hair pixels with an adaptive median filter. I tried this code but it's not correct:
%load image
image = im2double(imread('hair.bmp'));
grayscale = rgb2gray(image);
%get hairs using close operation
se = strel('disk',5);
hairs = imclose(grayscale ,se);
lab_mask = bwlabel(hairs);
stats = regionprops(lab_mask, 'MajorAxisLength', 'MinorAxisLength');
%identifies long, thin objects
Aaxis = [stats.MajorAxisLength];
Iaxis = [stats.MinorAxisLength];
idx = find((Aaxis ./ Iaxis) > 4); % Selects regions that meet logic check
out_mask = ismember(lab_mask, idx);
figure, imshow(out_mask);
replacedImage = roifill(grayscale, hairs);
figure, imshow(replacedImage);
bwlabel works on binary images so you need to do a threshold after the closing.
hairs = hairs < 130; % or whatever. Then do bwlabel.
I inserted your suggestion in the code(is it correct?) but I got complete blurred image %load image image = im2double(imread('hair.bmp')); grayscale = rgb2gray(image); %get hairs using close operation se = strel('disk',5); hairs = imclose(grayscale ,se); hairs = hairs < 130; % or whatever. Then do bwlabel. lab_mask = bwlabel(hairs); stats = regionprops(lab_mask, 'MajorAxisLength', 'MinorAxisLength'); %identifies long, thin objects Aaxis = [stats.MajorAxisLength]; Iaxis = [stats.MinorAxisLength]; idx = find((Aaxis ./ Iaxis) > 4); % Selects regions that meet logic check out_mask = ismember(lab_mask, idx); figure, imshow(out_mask); replacedImage = roifill(grayscale, hairs); figure, imshow(replacedImage)
Sorry,I could n't past the code as shown in MATLAB
I attached sample image contains hair (hair.bmp)
Image Analyst,could you correct my code please,thank you in advance.

Sign in to comment.

Tags

Asked:

on 8 Sep 2012

Commented:

on 29 Sep 2013

Community Treasure Hunt

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

Start Hunting!