How to create a rectangular mask based on current code for making an elliptical mask

I have an code that creates an elliptical mask and rotates it to a certain angle:
for k = 0:180/deltaK:180-1 % Loop to Rotate the mask in steps.
if rectMask == 0
% Create circular mask.
x = ones(round(diamMax+0.5),1)*(1:round(diamMax+0.5))-round(diamMax+0.5)/2; % Distance in x-direction to centre.
y = (1:round(diamMax+0.5))'*ones(1,round(diamMax+0.5))-round(diamMax+0.5)/2; % Distance in y-direction to centre.
r = sqrt(x.^2+y.^2); % Absolute distance to centre.
maskMax = double(r <= diamMax/2);
% Create mask to convolve the image with.
maskMin = double(abs(x) <= diamMin/2);
maskMin = imrotate(maskMin, k); % Rotation of the mask.
lMaskMax = length(maskMax);
lMaskMin = length(maskMin);
if round(k/90) ~= k/90
maskMin = maskMin(round((lMaskMin-lMaskMax)/2+1.5):round(lMaskMin-...
(lMaskMin-lMaskMax)/2+0.5), round((lMaskMin-lMaskMax)/2+1.5):...
round(lMaskMin-(lMaskMin-lMaskMax)/2+0.5));
end % if
mask = double(maskMax & maskMin);
else % use rectangular mask
% code for creating rectangular mask
% ...
end % if end
end % end for
I would like to replace the elliptical mask if I choose (that is, I want to have both options available by setting a parameter rectMask), with an rectangular mask of with the same size and rotation. How can I do this based on current code?
My input data here are:
  • diamMax
  • diamMin
  • k
  • rectMask = 1 or 0

 Accepted Answer

I don't understand how your current code works, but you might consider modifying the code below, as appropriate:
M=256; N=256; %Image dimensions
diamMax=60; diamMin=40;
k=30;
imshow(getMask('rect',M,N,diamMin,diamMax,k))
imshow(getMask('ellipse',M,N,diamMin,diamMax,k))
function Mask=getMask(shape,M,N,diamMin,diamMax,k)
x=(1:M)-(M+1)/2;
y=(1:N)'-(N+1)/2;
switch shape
case 'ellipse'
Mask=(x/diamMax).^2 + (y./diamMin).^2<=1;
case 'rect'
Mask=max(abs(x)/diamMax,abs(y)/diamMin)<=1;
end
Mask=imrotate(Mask,k);
end

4 Comments

I have an code that also plot the mask per angle for an ellipse, but I have an hard time understanding the plotting part. Outside the loop that to through different angles, in above in previous post, Qm = 0; Inside loop my code after creating the mask is:
Qm_k = conv2(image_calib, Mask,'same'); % Convolution of the mask and the image to analyse.
Qm_k = gather(Qm_k);
if Qm < max(Qm_k(:))
Qm = max(Qm_k(:));
k_vect = k;
%disp('found a result')
end % end if
[~,hor_center] = max(max(Qm_k,[],1));
[~,ver_center] = max(max(Qm_k,[],2));
rotx = @(x,y,k) x*cos(k*pi/180) - y*sin(k*pi/180);
roty = @(x,y,k) x*sin(k*pi/180) + y*cos(k*pi/180);
% plotting the rotated ellipse
t=linspace(-pi,pi,50);
x_ellipse=hor_center + rotx(diamMin/2*cos(t),diamMax/2*sin(t),-k);
y_ellipse=ver_center + roty(diamMin/2*cos(t),diamMax/2*sin(t),-k);
plot(x_ellipse,y_ellipse,'r');
If I want to mark the shape of the mask on my image that I am analysing (called image_calib) at the worst case angle (which should be at an angle that gives max value of Qm_k).
I want to plot an line instead of the filled mask (a line of either rectangle or ellipse shape) to highlight the worst case angle in my image which gives max Qm. How could I do this for all the different shapes? Someohow I need to know the location of max intensity? It is that which I can't understand how my current code it finds it. I am guessing it is "max(max(Qm_k,[],1))".
Thanks for the help.
Ok, I have reviewed the previous code and i am not getting the same size on the mask of my orginal code.
The mask in my original code is 38x38 pixlar (becuase diamMax, diamMin = 38). The size of the mask in your code is about 72 pixlar and the whole image is case 113 x121. The whole image is larger than the mask.
For some reason the size of the mask itself (which is for k = 0 a circular mask becuase at first I set diamMax and diamMin is equal values) is larger in your code. I can't figure out why.
Just divide the diams in half
function Mask=getMask(shape,M,N,diamMin,diamMax,k)
diamMin=diamIn/2;
diamMask=diamMask/2;
...
end

Sign in to comment.

More Answers (1)

You could also just use poly2mask. This would avoid the overhead of imrotate.
M=256; N=256; %Image dimensions
diamMax=60; diamMin=40;
k=30;
imshow(getMask('rect',M,N,diamMin,diamMax,k))
imshow(getMask('ellipse',M,N,diamMin,diamMax,k))
function Mask=getMask(shape,M,N,diamMin,diamMax,k)
switch shape
case 'ellipse'
p=nsidedpoly(1000);
case 'rect'
p=nsidedpoly(4);
end
p=scale(p,[diamMax,diamMin]);
p=translate( rotate(p,-k) ,[M/2,N/2]);
V=p.Vertices;
Mask=poly2mask(V(:,1),V(:,2), M,N);
end

Products

Release

R2021b

Asked:

on 4 Aug 2022

Commented:

on 5 Aug 2022

Community Treasure Hunt

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

Start Hunting!