Circles misplaced in MATLAB - 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.

Related

Swift Draw a line from center of one circle to the edge of another

I am trying to draw a UIBezierPath in swift where i can get it to go from the center of a circle to another circles center but what i really want is for the line to stop at the edge of the end circle but at the point where the line would have intersected the circles edge if the line was continuating to the center of the circle and not stopping at the edge.
I need somehow to calculate the intersection point between the line and the circle. how would i be able to do that when the circles are UIImageViews with width and height of 30 (so radius 15) and i now the centers coordinates of the two circles.
I have found a solution.
From the the set of x and y (center of circles) from now called (x, y) and (x2, y2) a vector can be made that is (x2 - x, y2 - y) where x2 - x i will call a and y2 - y i will call b then the distance of the vector can be calculates as sqrt(a^2 + b^2) where the result of i will call dist.
From this a Unit vector can be made with is (a/dist, b/dist) now all i need to do to get my new coordinates for the arrow is (x,y) as starting coordinates and (x2 + ra/dist, y2 + rb/dist) as the end coordinates where r is the radius of the circle at (x2, y2).

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:

How can I obtain the bounding box of an object to separate it from the background [duplicate]

I have background subtracted images as input. The idea is to reduce search areas for person detection by using a smaller search area for the HOG algorithm. The output required is a bounding box around the person and the pixel positions of the box corners.
This is the input image:
This is the required output:
This is what I have tried so far:
x=imread('frame 0080.png');
y=im2bw(x);
s=regionprops(y);
imshow(y);
hold on
for i=1:numel(s)
rectangle('Position',s(i).BoundingBox,'edgecolor','y')
end
This was the output I got:
It looks like you have tried what I have suggested. However, you want the bounding box that encapsulates the entire object. This can easily be done by using the BoundingBox property, then calculating each of the four corners of each rectangle. You can then calculate the minimum spanning bounding box that encapsulates all of the rectangles which ultimately encapsulates the entire object.
I do notice that there is a thin white strip at the bottom of your image, and that will mess up the bounding box calculations. As such, I'm going to cut the last 10 rows of the image before we proceed calculating the minimum spanning bounding box. To calculate the minimum spanning bounding box, all you have to do is take all of the corners for all of the rectangles, then calculate the minimum and maximum x co-ordinates and minimum and maximum y co-ordinates. These will correspond to the top left of the minimum spanning bounding box and the bottom right of the minimum spanning bounding box.
When taking a look at the BoundingBox property using regionprops, each bounding box outputs a 4 element vector:
[x y w h]
x,y denote the top left co-ordinate of your bounding box. x would be the column and y would be the row of the top left corner. w,h denote the width and the height of the bounding box. We would use this and compute top left, top right, bottom left and bottom right of every rectangle that is detected. Once you complete this, stack all of these rectangle co-ordinates into a single 2D matrix, then calculate the minimum and maximum x and y co-ordinates. To calculate the rectangle, simply use the minimum x and y co-ordinates as the top left corner, then calculate the width and height by subtracting the maximum and minimum x and y co-ordinates respectively.
Without further ado, here's the code. Note that I want to extract all of the bounding box co-ordinates in a N x 4 matrix where N denotes the number of bounding boxes that are detected. You would have to use reshape to do this correctly:
% //Read in the image from StackOverflow
x=imread('http://i.stack.imgur.com/mRWId.png');
% //Threshold and remove last 10 rows
y=im2bw(x);
y = y(1:end-10,:);
% //Calculate all bounding boxes
s=regionprops(y, 'BoundingBox');
%// Obtain all of the bounding box co-ordinates
bboxCoords = reshape([s.BoundingBox], 4, []).';
% // Calculate top left corner
topLeftCoords = bboxCoords(:,1:2);
% // Calculate top right corner
topRightCoords = [topLeftCoords(:,1) + bboxCoords(:,3) topLeftCoords(:,2)];
% // Calculate bottom left corner
bottomLeftCoords = [topLeftCoords(:,1) topLeftCoords(:,2) + bboxCoords(:,4)];
% // Calculate bottom right corner
bottomRightCoords = [topLeftCoords(:,1) + bboxCoords(:,3) ...
topLeftCoords(:,2) + bboxCoords(:,4)];
% // Calculating the minimum and maximum X and Y values
finalCoords = [topLeftCoords; topRightCoords; bottomLeftCoords; bottomRightCoords];
minX = min(finalCoords(:,1));
maxX = max(finalCoords(:,1));
minY = min(finalCoords(:,2));
maxY = max(finalCoords(:,2));
% Draw the rectangle on the screen
width = (maxX - minX + 1);
height = (maxY - minY + 1);
rect = [minX minY width height];
% // Show the image
imshow(y);
hold on;
rectangle('Position', rect, 'EdgeColor', 'yellow');
This is the image I get:

How to draw a circle with perspective transformation

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.