Clear Filters
Clear Filters

How can I get the average color of a ROI (mask) ?

31 views (last 30 days)
Mona
Mona on 21 May 2024 at 14:18
Answered: Fake Name Johnson on 22 May 2024 at 5:17
Hello !
I'm doing a project for school and I have a picture that I divided in several ROI.
I used roipoly in matlab to select the ROI. Now, I would like to get the average color inside the area of the mask and replace each pixels but the average color. Here is my code :
averageColors = zeros(sum(mask(:)), 3);
for i = 1:3
channel = image(:,:,i);
averageColors(:,i) = accumarray(find(mask(:)), channel(mask(:)), [], @mean);
end
result = image;
for i = 1:3
result(:,:,i) = accumarray(find(mask(:)), averageColors(:,i), [], @mean);
end
I get an error on ligne 4 :
Unable to perform assignment because the size of the left side is 30683-by-1 and the size of the right side is 421368-by-1.
I don't understand... find(mask(:)) and channel(mask(:)) have the same size...
Thank you for reading !

Answers (2)

Pratyush Swain
Pratyush Swain on 21 May 2024 at 20:19
Hi Mona,
Given you have a selected a ROI in a picture and would want to replace each pixel inside the area of mask with the average color, you can follow a simpler approach without using the "accumarray" function.Please refer to a demo example as follows:
% Making a test image with a circular ROI %
% -------------------------------------------- %
% Form a random test image of dimensions 100X100X3
image = zeros(100, 100, 3);
image(1:50, :, 1) = 0.8;
image(51:end, :, 2) = 0.8;
image(:, 51:end, 3) = 0.5;
% Making a circular ROI
[X, Y] = meshgrid(1:100, 1:100);
center = [50, 50];
radius = 25;
mask = (X - center(1)).^2 + (Y - center(2)).^2 <= radius^2;
% --------------------------------------------- %
% Initialize the result image
result = image;
% Loop through each color channel
for i = 1:3
channel = image(:,:,i);
% Calculate the average color within the mask
averageColor = mean(channel(mask));
% Replace the pixels in the mask with the average color
channel(mask) = averageColor;
% Allot the updated pixels in the result image in the respective color channel
result(:,:,i) = channel;
end
figure;
subplot(1,3,1);
imshow(image);
title('Original Image');
subplot(1,3,2);
imshow(mask);
title('Masked Image');
subplot(1,3,3);
imshow(result);
title('Image with Average Color')
Hope this helps

Fake Name Johnson
Fake Name Johnson on 22 May 2024 at 5:17
There are other ways to do this, but let's be simple. Assuming a single-channel logical mask:
% an image (RGB, uint8)
inpict = imread('peppers.png');
szi = size(inpict,1:3); % get the size of the image
% a mask (logical)
mask = imread('redpepmask.png')>128;
mask = repmat(mask,[1 1 szi(3)]); % expand to match the image depth
% get the mean color
meancolor = mean(reshape(inpict(mask),[],1,szi(3)),1);
% assemble the output image
outpict = inpict;
outpict(mask) = repmat(meancolor,[nnz(mask)/szi(3) 1 1]);
% show the result
imshow(outpict,'border','tight')
... or you could just use the loops.

Products

Community Treasure Hunt

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

Start Hunting!