how to get the threshold automatically when converting image from hsv to bw

조회 수: 6 (최근 30일)
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.
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
Guillaume
Guillaume 2017년 11월 9일
편집: Guillaume 2017년 11월 9일
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
Ziming Zhong 2017년 11월 9일
@Akira Agata @Guillaume Thanks Akira and Guillaume! K-Means doesn't work well either, as it can't distinguish the yellowish colony with yellowish media, even though the colony is dark. I don't really see why. I'm also thinking to use edge detection, but doesn't work at all. I don't know whether its somehow I got something wrong.

댓글을 달려면 로그인하십시오.

채택된 답변

Ziming Zhong
Ziming Zhong 2017년 11월 13일
편집: Ziming Zhong 2017년 11월 13일
Hmm, I just want to update my question here.
Finally, I don't need to set the threshold separately for each image. I just converted the image from RGB to HSV and then to YCBCR. After the second conversion, the threshold for YCBCR to BW is more or less the same for every image, no matter how different the colony color and size. I'm not really sure whether it is proper to do two conversions. But at least it works.
I also tried to convert RGB directly to YCBCR, but the result is not as good as through two conversions.
The only problem that I still have is that imfindcircles() on bw image doesn't really work well even though I played with the sensitivity and EdgeThreshold, and I don't know why. Do somebody know the possible reason?
  댓글 수: 1
Ziming Zhong
Ziming Zhong 2017년 11월 15일
I guess its better i list my codes here:
hsvIm = rgb2hsv(a); % convert RGB image a to hsv format; 1st convertion
ycb = rgb2ycbcr(hsvIm); % convert to ycbcr format; 2nd convertion
imshow(ycb);
histogram(ycb(:,:,1)); % check the histogram to decide the threshold
bwIm = ycb(:,:,1) < 0.35; % I had tested 25 images by using this threshold, and all of them resulted in perfect masks.
I started to try more image format conversions after the suggestions and finally can find this solution. Thank everybody who gave me suggestions on this question!!!

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Image Analyst
Image Analyst 2017년 11월 7일
Since they seem to all be circular, have you tried imfindcircles()?
  댓글 수: 5
Image Analyst
Image Analyst 2017년 11월 9일
Exactly what regions are you trying to find? The whole bullseye, or just the center, or something else?

댓글을 달려면 로그인하십시오.


Image Analyst
Image Analyst 2017년 11월 14일
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
Ziming Zhong
Ziming Zhong 2017년 11월 15일
Thank you very much for the codes! I had tried your code through 25 images containing colonies (so far I have) in different shapes and colours. On some of the images, this code works perfectly. But for some colonies, the code still got problems and I guess still the large range of thresholds among images caused problem. Comparing the results from this code with results from two image format conversions (as I mentioned above), I think I will try the two image conversions method to analyse all my colonies.
Thank you very much again for the codes!!!!!

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Graph and Network Algorithms에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by