Reputation: 749
I have a image of low resolution, 128x128 pixels. I need to obtain the mean value of a circle ROI, in order to do that I use the easy method:
%% Draw circle ROI
t = 0:pi/500:2*pi;
xi = ((R0/pixelSize)*cos(t)+63.5+x0+((Rsphere)/pixelSize)*cos(theta))*4;
yi = ((R0/pixelSize)*sin(t)+63.5+y0+((Rsphere)/pixelSize)*sin(theta))*4;
%% Calculate roi statistics
line(xi,yi,'LineWidth',1,'Color',color);
ROImask = poly2mask(xi,yi, size(im,1),size(im,2));
ptROI = find(ROImask);
ROImean = mean(im(ptROI));
The problem here is that using this method I don't account for the partial value of a pixel in the ROI, as can be seen in the image.
Is there any direct way to obtain the mean of the ROI weighting the value of the pixels?
Thanks
Upvotes: 3
Views: 577
Reputation: 1215
If you really want to do this exactly, you'll need to do some calculus (integral of a circle on a square domain for each pixel). But, this probably overkill for your application. My suggestion is to calculate your circle on a fine grid, then resize it to match the image:
upFactor = 3;
% load built-in example image
x = imread('rice.png');
% convert to double
x = im2double(x);
% define the ROI
center = [68.5, 180]; % [row, column]
radius = 1; % pixels
% do the distance calculation
% (getting the coordinate systems to match is the hardest part, try making
% small examples to see how it works)
iVector = (0:size(x,1)*upFactor-1)/upFactor + .5 + 1/upFactor/2;
jVector = (0:size(x,2)*upFactor-1)/upFactor + .5 + 1/upFactor/2;
[I, J] = ndgrid( iVector - center(1), jVector - center(2));
sqDist = I.^2 + J.^2;
insideBig = double(sqDist <= radius^2); % need this to not be logical type
% this resizes back to the original image size my taking the mean of each
% upFactor by upFactor block
inside = reshape( mean( im2col( insideBig, [upFactor upFactor], 'distinct')), size(x));
% check that we have the values we expect
uniqueVals = unique(inside(:))
% show examples
figure
imagesc(x)
figure
imagesc(inside)
result = sum(sum( x .* inside )) / sum(inside(:))
Upvotes: 1