How to draw a circle with perspective transformation - matlab

I want to draw a circle with perspective tansformation in Matlab. Here I have used sample of code to draw a circle. If I rotate this circle using perspective tansform this must be ellipse. I want to draw both axis rotation(X & Y) of a circle. Now I am struggled to draw a perspetive rotation of this circle.
I need to use radious of the circle, x axis roation angle and y axis roation angle as input parameters.
Rimg = zeros(600,600);
ri = 100;
xcentre = 300;
ycentre = 300;
for r = 0:ri
for rad = 0:(pi/720):(2*pi)
xi = round(xcentre+(r*cos(rad)));
yi = round(ycentre+(r*sin(rad)));
Rimg(xi,yi) = 1;
end
end
imshow(Rimg,[]);
The first image shows my circle and the second image shows the expected result. This is only rotated in x axis. But I need both axis rotation in a single image.

Related

Adjust regionprops orientation to 0-360 degrees (Matlab)

I would like to align video frames to center and reorient an animal walking across the frames. I binarized each frame and fit an ellipse to the animal's body.
Binarized with ellipse fit
I used regionprops to find the ellipse, which outputs orientation from -90 to 90 degrees. I rotate each frame depending on the difference between orientation and the desired alignment orientation. The problem I'm having is that sometimes the orientation is aligned to the head and sometimes to the tail, so the alignment is occasionally 180 degrees flipped.
Upright position
Flipped position
I think this can be resolved by putting the orientation output in 0-360 space. Does anyone have a solution for this?
Here is my code:
for i = 1000
frame = read(v,i);
BW = im2bw(frame,0.95);
imshowpair(frame,BW,'montage')
% Extract the maximum area
BW = imclearborder(BW);
BW = bwareafilt(BW,1);
% Calculate centroid, orientation and major/minor axis length of the ellipse
s = regionprops(BW,{'Centroid','Orientation','MajorAxisLength','MinorAxisLength'});
centroid(i,:) = s.Centroid;
orientation(i) = s.Orientation;
fixed_orientation(i) = s.Orientation;
delta_angle(i) = -90 - orientation(i);
if i >=2
if diff(sign( fixed_orientation(i-1:i) )) == 2 && abs(fixed_orientation(i-1))-abs(fixed_orientation(i))>=20
fixed_orientation(i) = -fixed_orientation(i);
delta_angle(i) = -(-90 - fixed_orientation(i));
end
end
% Calculate the ellipse line
theta = linspace(0,2*pi);
col = (s.MajorAxisLength/2)*cos(theta);
row = (s.MinorAxisLength/2)*sin(theta);
M = makehgtform('translate',[s.Centroid, 0],'zrotate',deg2rad(-1*s.Orientation));
D = M*[col;row;zeros(1,numel(row));ones(1,numel(row))];
% Visualize the result
figure
imshow(BW)
hold on
plot(D(1,:),D(2,:),'r','LineWidth',2)
end
figure
for i = 1:1000
rotate_filler = imrotate(read(v,i), delta_angle(i), 'crop');
rotated_image(:,:,:,i) = rotate_filler;
imshowpair(read(v,i), rotated_image(:,:,:,i), 'montage')
pause(0.001)
end
Any suggestions are appreciated. Thanks!

Estimating an ellipse with a multi-variate Gaussian

In MATLAB, say I have the parameters for an ellipse:
(x,y) center
Minor axis radius
Major axis radius
Angle of rotation
Now, I want to generate random points that lie within that ellipse, approximated from a 2D gaussian.
My attempt thus far is this:
num_samps = 100;
data = [randn(num_samps, 1)+x_center randn(num_samps, 1)+y_center];
This gives me a cluster of data that's approximately centered at the center, however if I draw the ellipse over the top some of the points might still be outside.
How do I enforce the axis rules and the rotation?
Thanks.
my assumptions
x_center = h
y_center = k
Minor Axis Radius = b
Major Axis Raduis = a
rotation angle = alpha
h=0;
k=0;
b=5;
a=10;
alpha=30;
num_samps = 100;
data = [randn(num_samps, 1)+h randn(num_samps, 1)+k];
chk=(((((data(:,1)-h).*cos(alpha)+(data(:,2)-k).*sin(alpha))./a).^2) +...
(((data(:,1)-h).*sin(alpha)+(data(:,2)-k).*cos(alpha))./b).^2)<=1;
idx=find(chk==0);
if ~isempty(idx)
data(idx,:)=data(idx,:)-.5*ones(length(idx),2);
end

Make a circle inside a matrix in Matlab

I want to make a circle inside a matrix. For example; Make a matrix of some dimension, let's say ones(200,200) and then select its circle's x and y co-ordinates and change the color of these selected pixels and then show the image using imshow(img). As showing in the picture. Is it possible?
OR
Can I change this ploting code to picture for using the circle functionality?
radius = 5;
centerX = 20;
centerY = 30;
viscircles([centerX, centerY], radius);
axis square;
You can use meshgrid to create a grid of x and y coordinates and then use the equation of the circle to check whether each x/y pair is within the circle or not. This will yield a logical result which can be displayed as an image
[x,y] = meshgrid(1:200, 1:200);
isinside = (x - centerX).^2 + (y - centerY).^2 <= radius^2;
imshow(isinside);
If you simply want the outline of the circle, you can apply a convolution to the resulting binary mask to decrease it's size and then subtract out the circle to yield only the outline
shrunk = ~conv2(double(~isinside), ones(3), 'same');
outline = isinside - shrunk;
imshow(outline)
If you have the Image Processing Toolbox, you can use bwperim to yield the binary outline
outline = bwperim(isinside);
imshow(outline);
Update
If you want to change the colors shown above, you can either invert outline and isinside before displaying
isinside = ~isinside;
outline = ~outline;
imshow(isinside)
imshow(outline)
Or you can invert the colormap
imshow(isinside)
colormap(gca, flipud(gray))

How to rotate a bounding box at any angle in matlab?

I felt confused to crop an image along any angle, i.e. pi/4, how can I make it?
The following example demonstrates how to crop rotated bounding box.
The example doesn't show how to select the bounding box, and the angle (user interface is excluded).
For keeping the example simple, the bounding box parameters are: center, size and angle (instead of 4 corners).
Center is kept in place, when rotating.
Size is the width and height of destination crop area (size after rotation).
In case you need to calculate corners transformation, you can use rotation matrix: https://en.wikipedia.org/wiki/Rotation_matrix
Code sample:
%Bounding box parameters: center, width, height and angle.
%Center is selected, because center is kept the same when rotating.
center_x = 256; %Center column index (applied center is 256.5)
center_y = 192; %Center row index (applied center is 192.5)
width = 300; %Number of columns of destination (cropped) area (even integer)
height = 200; %Number of rows of destination (cropped) area (even integer)
phi = 120; %Rotation angle in degrees
%Read sample image.
I = imread('peppers.png');
%Add center cross, for verifying center is kept.
I(center_y-1:center_y, center_x-30:center_x+30, :) = 255;
I(center_y-30:center_y+30, center_x-1:center_x, :) = 255;
%Rotate the entire input image, dimensions of J will be the same as I.
J = imrotate(I, phi, 'bicubic', 'crop');
%Crop rectangular are with size width by height around center_x, center_y from J.
C = J(center_y-height/2+1:center_y+height/2, center_x-width/2+1:center_x+width/2, :);
%Display result:
figure;imshow(C);
Result:

Circles misplaced in MATLAB

I'm trying to draw a circle on an image in MATLAB with given X,Y coordinates and radius. Here's the chuck of code of method that draws multiple circles for me -
function circle( Xs, Ys, Rs, LineWidth, LineColor)
radius = Rs;
centerX = Xs;
centerY = Ys;
for i=1:length(centerX)
rectangle('Position',[centerX(i), centerY(i), radius(i), radius(i)],...
'Curvature',[1,1],...
'LineWidth',LineWidth,...
'LineStyle','-',...
'EdgeColor',LineColor);
end
end
But whenever I see the circles in an image, I see that the circles are a little bit misplaced from the given coordinates (for example, they moved a little bit right/down). How do I fix this problem?
What you are drawing is actually a rectangle. But you have a curvature defined, which makes it look like a circle. The circle is then defined by a bounding box with the coordinates of the rectangle. The Position of the rectangle is the upper left corner (or in a regular plot the lower left corner) and what you called the radius is actually the width and height of that bounding box.
This is what I mean:
>> figure, imshow(I)
>> rectangle('Position',[100,100,120,120],'Curvature',[1,1])
>> rectangle('Position',[100,100,120,120],'Curvature',[0,0],'EdgeColor','r')
>> axis on
This code will produce a circle and a rectangle both in the same position defined by the same rectangle coordinates in the upper left corner. The red one is the bounding box I am speaking of.
Edit: If you don't want to use the rectangle function you could maybe do the following:
>> figure,imshow(I)
>> hold on
>> plot(centerX+radius*sin(0:0.1:2*pi),centerY+radius*cos(0:0.1:2*pi))
Try the following:
function circle( Xs, Ys, Rs, LineWidth, LineColor)
radius = Rs;
centerX = Xs;
centerY = Ys;
xStart = centerX - radius;
yStart = centerY - radius;
for i=1:length(centerX)
rectangle('Position',[xStart(i) , yStart(i) , radius(i), radius(i)],...
'Curvature',[1,1],...
'LineWidth',LineWidth,...
'LineStyle','-',...
'EdgeColor',LineColor);
end
end
I hope this will work.
By subtracting the radius from the center points we can get the starting point(Top left corner) of the rectangle with curvature [1,1], that is nothing but the circle.