Clear Filters
Clear Filters

Can I apply a graylevel mask on a color image?

1 view (last 30 days)
Hi everyone, I have an RGB image(n by m by 3) that i segmented it using watershed algorithm. The output of the segmentation is a graylevel image (n by m) which contains the labels assigned to each region of the image. I want to calculate the average of each region's color of the original image but i don't find how to define each region of the original color image. Is it possible to consider the output of the watershed (the graylevel image) as a mask of my original image? If not, can anyone please suggest another solution? Thank you for your answer.
  3 Comments
As Bdg
As Bdg on 24 Jul 2017
Thank you for your reply Adam ; but how can i apply the mask to each layer when it is not binary , it contains the labels of the regions, and i want to conserve these labels.
Adam
Adam on 24 Jul 2017
You would have to take 1 label at a time to create a binary mask for that particular label. Or just follow Guillaume's answer. I almost never use regionprops so I don't know much about it, but Guillaume's answers generally work fine.

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 24 Jul 2017
It can be done any numbers of ways. Probably the simplest is to use regionprops on your label image and ask for the 'PixelIdxList' of each blob. This is gives you the linear pixel index of each blob in each channel. You could then just loop over the blobs and channels to compute the mean:
blobprops = regionprops(yourlabelimage, 'PixelIdxList');
channelmeans = zeros(numel(blobprops), size(yourimage, 3)); %using size(img, 3) so that it works with rgb and greyscale images
for channel = 1:size(yourimage, 3)
imagechannel = yourimage(:, :, channel);
for blob = 1:numel(blobprops)
channelmeans(blob, channel) = mean(imagechannel(blobprops(blob).PixelIdxList));
end
end
Or you can use the 'PixelList' instead, repmat that for each colour channel, convert to linear index, extract the pixels and reshape into 3D to avoid the channel loop:
blobprops = regionprops(yourlabelimage, 'PixelList');
channelmeans = zeros(numel(blobprops), size(yourimage, 3)); %using size(img, 3) so that it
for blob = 1:numel(blobprops)
allpixelsidx = reshape(sub2ind(size(yourlabelimage), [repmat(blobprops(blob).PixelList, [3 1]), repelem([1;2;3], size(blobprops(blob).PixelList, 1)]), [], 3);
channelmeans(blob, :) = mean(yourimage(allpixelsidx), 2);
end
  3 Comments
Guillaume
Guillaume on 25 Jul 2017
Edited: Guillaume on 25 Jul 2017
Once you've got the mean it's trivial to replace the blob pixels by the mean value. You've already got the list of blob pixels in PixelIdxList or PixelList. e.g. with the first method:
blobprops = regionprops(yourlabelimage, 'PixelIdxList');
for channel = 1:size(yourimage, 3)
imagechannel = yourimage(:, :, channel);
for blob = 1:numel(blobprops)
imagechannel(blobprops(blob).PixelIdxList) = mean(imagechannel(blobprops(blob).PixelIdxList)); %replace blob pixels by mean for channel
end
yourimage(:, :, channel) = imagechannel; %and put channel back into image
end
I've just though of a method which is even simpler, using accumarray:
numblobs = max(yourlabelimage(:)) + 1; %also include backgrounds
subs = [yourlabelimage(:) + 1; yourlabelimage(:) + numblobs + 1; yourlabelimage(:) + 2*numblobs + 1]; %add numblobs to accumulate green, 2*numblobs to accumulate blue
channelmeans = reshape(accumarray(subs, yourimage(:), [], @mean), [], 3);
Note that row 1 of channelmeans is the background mean. row 2 is label 1, etc.
With the above, it is also trivial to assign the mean back to each blob (and background mean):
meanimage = channelmeans(reshape(subs, size(yourimage))); %That's all!
As Bdg
As Bdg on 25 Jul 2017
Sorry for the disruption, but it seems that i don't well your answer. I need to have a (m by n) matrix that will be obtained by replacing each label of the initial watershed segmentation by the mean colorvalue of the corresponding region in my original image (m by n by 3). and the watershed lines are removed by setting the new matrix(n by m) = the original one (n by m by 3) at all regions borders (i.e. the watershed lines are replaced by the corresponding colorvalues of the original color image. Can you help me more please? I really don't know how to proceed. Thanks again

Sign in to comment.

More Answers (0)

Categories

Find more on Convert Image Type in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!