Highlighting a Region of interest and getting the average Hue value ?

12 views (last 30 days)
Reinhard Tan
Reinhard Tan on 25 Sep 2018
Answered: DGM on 20 May 2022
So I'm trying to select a specific area of an HSV (Hue, saturation, value) image by drawing a rectangle on the area I'm interested in. After selecting the area, I want to be able to read this segmented area's HSV average values.
%% RGB to HSV
img1 = imread('Apple 1.jpg');
rgb = img1;
hsv = rgb2hsv(rgb); % Compute the HSV values from the RGB data
h = hsv(:,:,1);
s = hsv(:,:,2);
v = hsv(:,:,3);
h_component=hsv(:,:,1); %H Component
s_component=hsv(:,:,2); %S Component
v_component=hsv(:,:,3); %IComponent
avgH = mean(h(:)); % Find the average HSV values across the image
avgS = mean(s(:));
avgV = mean(v(:));
figure
imshow(h)
h = imrect;
imtool(h);
  2 Comments
Reinhard Tan
Reinhard Tan on 25 Sep 2018
Sorry if i wasn't clear. I simply to get the H value of just a certain area of an image preferably selecting it with a rectangular box.

Sign in to comment.

Accepted Answer

Image Analyst
Image Analyst on 25 Sep 2018
You're getting the mean of the whole image. You need to call imrect() BEFORE you take the mean. Something like
hRect = imrect;
mask = hRect.createMask;
meanh = mean(h(mask));
means = mean(s(mask));
meann = mean(n(mask));
  1 Comment
Reinhard Tan
Reinhard Tan on 25 Sep 2018
Thanks for the speedy reply! It's exactly what I was looking for! Thank you :)

Sign in to comment.

More Answers (1)

DGM
DGM on 20 May 2022
Taking the mean of hues is not as simple as described, and it's likely an unnecessary complication. H is a circular continuum. In HSV, HSL, and HSI, colors in the vicinity of red are simultaneously near both 0 and 360. What is the mean value of 10 and 350?
Instead of using the arithmetic mean, you'd use the circular mean when dealing with angles. Consider the following example with this image:
% an image of peppers
A = imread('peppers.png');
% a mask to select only the large red pepper
mask = imread('redpepmask.png')>128;
Ahsv = rgb2hsv(A);
[H S V] = imsplit(Ahsv);
Hroi = H(mask);
% arithmetic vs circular mean (normalized angles)
meanH = mean(Hroi)
circmeanH = circmean(Hroi*360)/360
meanH =
0.7044
circmeanH =
0.9932
The calculated mean angles are different; why?
% why are they different?
subplot(1,2,1)
imshow(H)
subplot(1,2,2)
histogram(Hroi*360,128)
As described, the distribution of hues in that region is split unless you deal with the space as if it's properly circular.
But how bad is the error? Everybody averages hue with mean(); surely it's good enough. Well, let's see.
% what would the results look like?
meancolor1 = cat(3,meanH,mean(S(mask)),mean(V(mask)));
meancolor1 = reshape(hsv2rgb(meancolor1),1,3)
meancolor2 = cat(3,circmeanH,mean(S(mask)),mean(V(mask)));
meancolor2 = reshape(hsv2rgb(meancolor2),1,3)
meancolor3 = reshape(A(repmat(mask,[1 1 3])),[],3);
meancolor3 = mean(im2double(meancolor3),1)
meancolor1 =
0.2495 0.1115 0.7212
meancolor2 =
0.7212 0.1115 0.1364
meancolor3 =
0.7212 0.1347 0.1529
% use those colors to construct a swatch chart for comparison
cc = [meancolor1; meancolor2; meancolor3];
labels = {'HSV amean','HSV cmean','RGB'};
sz = imsize(A,2);
ntiles = (numel(labels));
tilesz = [round(sz(1)/ntiles) 100];
block1 = zeros([tilesz 3 ntiles],'uint8');
for k = 1:ntiles
thistile = colorpict([tilesz 3],cc(k,:)); % colored swatch
thislabel = im2uint8(textim(labels{k},'ibm-iso-16x9')); % text label image
thistile = im2uint8(imstacker({thislabel thistile},'padding',0)); % match geometry
block1(:,:,:,k) = mergedown(thistile,1,'lineardodge'); % blend label and swatch
end
block1 = imtile(block1,[ntiles 1]); % vertically arrange tiles
block1 = imresize(block1,[sz(1) tilesz(2)]); % make sure it's the right size
% show the combined images
clf
Amasked = replacepixels([0 0 0],A,~mask);
imshow([Amasked block1])
The answer is that the error is not subtle at all -- but only for image regions containing significant amounts of red. Note that the average color obtained using the circular mean in HSV is not much different than just using the simple arithmetic mean on RGB data. If all you need is an average color, do you actually have a good reason to do the work in another color space?
The attached function circmean() shows how to do the circular mean of angles.
The last part of the example where the swatch chart is constructed uses several other MIMT tools, though they are not necessary for the task described in the question.

Community Treasure Hunt

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

Start Hunting!