Clear Filters
Clear Filters

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

31 views (last 30 days)
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);
result = image;
for i = 1:3
result(:,:,i) = accumarray(find(mask(:)), averageColors(:,i), [], @mean);
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;
title('Original Image');
title('Masked Image');
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
... or you could just use the loops.


Community Treasure Hunt

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

Start Hunting!