how to get the threshold automatically when converting image from hsv to bw
Show older comments
Hi! I have to convert my image from HSV to BW to do all the analysis. But I have a lot of images and I can't adjust the threshold one by one. I have checked some of my images, and the threshold change from 0.1 to 0.4. SO the change is quite large and I can't use a single threshold for all the image.
So does somebody know how can I generate the threshold for each image without manually checking the histogram? I need to choose the threshold after the first pick in the histgram.
I asked a question related to this one before. More info: https://stackoverflow.com/questions/47024527/how-to-segment-the-colony-when-i-cant-use-bw-image
Some of my codes are here:
b=imread('test4.jpg')
hsvIm = rgb2hsv(b) % convert the image to hsv format
imshow(hsvIm)
histogram(hsvIm(:,:,1))
%thresholding on the hue space
bwIm = hsvIm(:,:,1) < 0.3 % the threshold can change from 0.1 to 0.4
I also attach some pictures here:



Thank you in advance!!!
11 Comments
Walter Roberson
on 4 Nov 2017
Sorry, No. We do not have any idea how you are judging whether part is foreground or background based on the hue. And why are you not taking into account that hue is an angle, so hue values "just before" hue 0 would have high hue ?
Image Analyst
on 4 Nov 2017
We cannot invent some adaptive automatic threshold algorithm for you, especially not having seen any of the images. It could be virtually anything -- how could we possibly know? You'll just have to look at the histograms and colorcloud and figure out something.
Ziming Zhong
on 5 Nov 2017
Ziming Zhong
on 5 Nov 2017
Walter Roberson
on 5 Nov 2017

If you look at this picture, you will see that values that you would identify as "red" happen both for hue near 0 and for hue near 360. If you were trying to segment by "red" then you would need to include hue less than some value and hue greater than some value. Low hue is on the "red to yellow" stretch, and high hue is on the "magenta to red" stretch. Red with a touch of yellow would have a low hue; red with a touch of magenta would have a high hue.
Akira Agata
on 7 Nov 2017
Ziming Zhong
on 9 Nov 2017
Guillaume
on 9 Nov 2017
what do you mean in your first comment that hue is a angle?
The HSV colour space is a cylinder where hue is the angular dimension (and S the radius, and V the height along the cylinder). Matlab encode all of these in the range 0-1, which for the hue maps to 0-360 degrees.
Ziming Zhong
on 9 Nov 2017
Walter point is that if you want to segment according to a red hue you need to consider hue values near 0 and hue values near 1 (360 degrees) since red is at both ends.
I would add to that that segmenting just using the hue is risky, you also ought to look at the saturation and value. Compare these three images:
figure;
subplot(1, 3, 1); imshow(hsv2rgb(repmat(cat(3, 0.2, 1, 1), 100, 100)));
subplot(1, 3, 2); imshow(hsv2rgb(repmat(cat(3, 0.2, 0.01, 0.01), 100, 100)));
subplot(1, 3, 3); imshow(hsv2rgb(repmat(cat(3, 0.2, 0.01, 0.99), 100, 100)))
They all have the same hue (0.2 == yellowish), yet only one of them look yellow. The other two have very low saturation (0.01) and vastly different values (0.01 and 0.99)
I would actually follow Akira's advice to use k-means clustering in the L*a*b* colour space.
Ziming Zhong
on 9 Nov 2017
Accepted Answer
More Answers (2)
Image Analyst
on 7 Nov 2017
0 votes
Since they seem to all be circular, have you tried imfindcircles()?
5 Comments
Ziming Zhong
on 8 Nov 2017
Edited: Ziming Zhong
on 8 Nov 2017
Image Analyst
on 9 Nov 2017
Have you tried a top hat filter or bottom hat filter?
Ziming Zhong
on 9 Nov 2017
Edited: Ziming Zhong
on 9 Nov 2017
Image Analyst
on 9 Nov 2017
Exactly what regions are you trying to find? The whole bullseye, or just the center, or something else?
Ziming Zhong
on 10 Nov 2017
Image Analyst
on 14 Nov 2017
Try this:
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 = 25;
%===============================================================================
% Get the name of the image the user wants to use.
baseFileName = 'lab_try.jpg';
folder = fileparts(which(baseFileName)); % Determine where demo folder is (works with all versions).
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
%===============================================================================
% Read in demo image.
rgbImage = imread(fullFileName);
% Get the dimensions of the image.
[rows, columns, numberOfColorChannels] = size(rgbImage);
% Display the original image.
subplot(2, 2, 1);
imshow(rgbImage, []);
axis on;
caption = sprintf('Original Color Image, %s', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
hp = impixelinfo();
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0.05 1 0.95]);
% 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.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Compute HSV image.
hsvImage = rgb2hsv(rgbImage);
saturationImage = hsvImage(:, :, 2);
valueImage = hsvImage(:, :, 3);
% Display the image.
subplot(2, 2, 2);
imshow(saturationImage, []);
axis on;
caption = sprintf('Saturation Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
hp = impixelinfo();
drawnow;
% Create the binary image.
binaryImage = saturationImage > 0.22 & valueImage > 0.1;
% Display the image.
subplot(2, 2, 3);
imshow(binaryImage, []);
axis on;
caption = sprintf('Binary Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
hp = impixelinfo();
drawnow;
% Take largest blobs only
binaryImage = bwareaopen(binaryImage, 20);
% Fill them to get rid of noise.
binaryImage = imfill(binaryImage, 'holes');
% Display the mask image.
subplot(2, 2, 4);
imshow(binaryImage, []);
axis on;
caption = sprintf('Binary Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
hp = impixelinfo();
drawnow;
props = regionprops(binaryImage, 'Area');
allAreas = sort([props.Area], 'descend')
1 Comment
Ziming Zhong
on 15 Nov 2017
Categories
Find more on Image Processing Toolbox in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
