Can I apply a graylevel mask on a color image?
1 回表示 (過去 30 日間)
古いコメントを表示
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 件のコメント
Adam
2017 年 7 月 24 日
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.
採用された回答
Guillaume
2017 年 7 月 24 日
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 件のコメント
Guillaume
2017 年 7 月 25 日
編集済み: Guillaume
2017 年 7 月 25 日
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!
その他の回答 (0 件)
参考
カテゴリ
Help Center および File Exchange で Convert Image Type についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!