I am looking for a way to isolate the x and/or y coord of a circle within a circle, as shown in the image.
I need to isolate this so i can set a condition that when a ball enters a circle, i can change some qualities of the ball, i have been able to do this for the outer circle, which is centred at [0 0] using the code below,
while sqrt(XY(1)^2 + XY(2)^2) < 5
but cannot figure out how to do it for the interior circles.
Thanks
If you know the center and the radius of the inner circles you are able to calculate the X and Y coordinates of the circles then, you can use the inpolygon function to thest if a point is inside a circle (inpolygon returns 1 if a point is inside the polygon, 0 otherwise). In this case the polygon is constitued by the points of the circles.
In the following code a point moves across three circles (two of them placed inside the bigger one).
The inpolygon function is used to test if the point (the ball) is inside a circle and in change its colour according to the circle it is inside to.
% Define the radius and centre of three circles
r1=10;
r2=3
r3=4
c1=[0 0];
c2=[3 3];
c3=[-4 -4]
% Calculate the X and Y coord of the three circles
t=0:.01:2*pi;
x=cos(t)*r1
y=sin(t)*r1
x1=cos(t)*r2+c2(1)
y1=sin(t)*r2+c2(2)
x2=cos(t)*r3+c3(1)
y2=sin(t)*r3+c3(2)
% Plot the circles
plot(x,y,'r')
hold on
plot(x1,y1,'g')
plot(x2,y2,'b')
daspect([1 1 1])
% Define the ball trajectory
mx=-10:1:10;
my=-10:1:10;
for i=1:length(mx)
% Plot the ball: black if outside of all the circle
mh=plot(mx(i),my(i),'o','markerfacecolor','k','markeredgecolor','k')
% If the ballk is inside the first circle, make it red
if(inpolygon(mx(i),my(i),x,y))
mh.MarkerFaceColor='r';
mh.MarkerEdgeColor='r';
end
if(inpolygon(mx(i),my(i),x1,y1))
% If the ballk is inside the second circle, make it green
mh.MarkerFaceColor='g';
mh.MarkerEdgeColor='g';
end
if(inpolygon(mx(i),my(i),x2,y2))
% If the ballk is inside the third circle, make it blue
mh.MarkerFaceColor='b';
mh.MarkerEdgeColor='b';
end
pause(1)
end
Hope this helps.
Qapla'
Related
I have a grayscale image I want to extract the regions of interest using detectSURFFeatures(). Using this function I get a surfPoints object.
by displaying this object on the image I get circles as regions of interest.
For my case I want the rectangular areas encompassing these circles.
To be more clear i have a image 1:
I want to extract Region of Interest (ROI) using : detectSURFFeatures(), we obtain the image
if you can see we have circular region, and for my case i want the rectangular ROI that contains the circular region :
It looks like the radius is fully determined by the points.Scale parameter.
% Detection of the SURF features:
I = imread('cameraman.tif');
points = detectSURFFeatures(I);
imshow(I); hold on;
% Select and plot the 10 strongest features
p = points.selectStrongest(10)
plot(p);
% Here we add the bounding box around the circle.
c = 6; % Correction factor for the radius
for ii = 1:10
x = p.Location(ii,1); % x coordinate of the circle's center
y = p.Location(ii,2); % y coordinate of the circle's center
r = p.Scale(ii); % Scale parameter
rectangle('Position',[x-r*c y-r*c 2*r*c 2*r*c],'EdgeColor','r')
end
And we obtain the following result:
In this example the correction factor for the radius is 6. I guess that this value correspond to half of the default Scale propertie's value of a SURFPoints object (which is 12.0). But since there is no information about that in the documentation, I can be wrong. And be carreful, the scale parameter of each ROI is not the same thing as the scale propertie of a SURFPoints object.
This question already has answers here:
How to straighten a tilted square shape in an image?
(2 answers)
Closed 5 years ago.
I have a cropped image of a card:
The card is a rectangle with rounded corners, is brightly colored, and sits on a relatively dark background.
It is, therefore, easy to differentiate between pixels belonging to the card and pixels belonging to the background.
I want to use MATLAB to rotate the card so its sides are vertical and horizontal (and not diagonal) and create an image of nothing but the straightened card.
I need this to work for any reasonable card angle (say +45 to -45 degrees of initial card rotation).
What would be the best way of doing this?
Thanks!
You can do this by finding the lines made by the edges of the card. The angle of rotation is then the angle between one of the lines and the horizontal (or vertical).
In MATLAB, you can use the Hough line detector to find lines in a binary image.
0. Read the input image
I downloaded your image and renamed it card.png.
A = imread('card.png');
We don't need color information, so convert to grayscale.
I = rgb2gray(A);
1. Detect edges in the image
A simple way is to use the Canny edge detector. Adjust the threshold to reject noise and weak edges.
BW = edge(I, 'canny', 0.5);
Display the detected edges.
figure
imshow(BW)
title('Canny edges')
2. Use the Hough line detector
First, you need to use the Hough transform on the black and white image, with the hough function. Adjust the resolution so that you detect all lines you need later.
[H,T,R] = hough(BW, 'RhoResolution', 2);
Second, find the strongest lines in the image by finding peaks in the Hough transform with houghpeaks.
P = houghpeaks(H, 100); % detect a maximum of 100 lines
Third, detect lines with houghlines.
lines = houghlines(BW, T, R, P);
Display the detected lines to make sure you find at least one along the edge of the card. The white border around the black background in your image makes detecting the right edges a bit more difficult.
figure
imshow(A)
hold on
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1), xy(:,2), 'LineWidth', 2, 'Color', 'red');
end
title('Detected lines')
3. Calculate the angle of rotation
lines(3) is the left vertical edge of the card. lines(3).point2 is the end of the line that is at the bottom. We want this point to stay where it is, but we want to vector along the line to be aligned with the vector v = [0 -1]'. (The origin is the top-left corner of the image, x is horizontal to the right and y is vertical down.)
lines(3)
ans =
struct with fields:
point1: [179 50]
point2: [86 455]
theta: 13
rho: 184
Simply calculate the angle between the vector u = lines(3).point1 - lines(3).point2 and the vertical vector v.
u = lines(3).point1 - lines(3).point2; % vector along the vertical left edge.
v = [0 -1]; % vector along the vertical, oriented up.
theta = acos( u*v' / (norm(u) * norm(v)) );
The angle is in radians.
4. Rotate
The imrotate function lets you rotate an image by specifying an angle in degrees. You could also use imwarp with a rotation transform.
B = imrotate(A, theta * 180 / pi);
Display the rotated image.
figure
imshow(B)
title('Rotated image')
Then you would have to crop it.
l have generated a topology of a network with 200 nodes.than l want to draw a circle with black color around a choosen node(satisfying a certain condition IF (condition) ).
to simplify let the user introduce the the index of the node to circle with the black color.
here is my code of the generated topology.l need to add wich instructions to draw the circle around the choosen node ?
X=100;
Y=100;
N=200; %number of nodes
nodesX(1)=rand*X;
nodesY(1)=rand*Y;
for i=2:N
nodesX(i)=rand*X;
nodesY(i)=rand*Y;
d(i-1) =((nodesX(i)-nodesX(i-1)).^2+(nodesY(i)-nodesY(i-1)).^2).^0.5;
while (d(i-1)>200)
nodesX(i)=rand*X;
nodesY(i)=rand*Y;
d(i-1) =((nodesX(i)-nodesX(i-1)).^2+(nodesY(i)-nodesY(i-1)).^2).^0.5;
end
end
h_old=plot(nodesX,nodesY,'m*');
labels=[1:N]';
labels=num2str(labels);
text(nodesX,nodesY,labels);
xlabel('X (Meters)');
ylabel('Y (Meters)');
title(['Network Topology with',num2str(N),'nodes']);
hold on
for k=1:N;
for j=1:N;
if (k~=j)
d=((nodesX(k)-nodesX(j))^2+(nodesY(k)-nodesY(j))^2)^0.5;
end
if (k~=j);
if(d < 50);
line([nodesX(k),nodesX(j)],[nodesY(k),nodesY(j)]);
end
end
end;
end;
Split it into two tasks:
Task 1:
Define a simple function to draw a circle. A cheap and dirty way is to use polar expressions.
function [] = circle(center_x,center_y,r)
theta = 0:0.01:2*pi;
x = center_x + r*cos(theta);
y = center_y + r*sin(theta);
plot(x,y,'k','LineWidth',2)
Task 2:
Pass this function the NodeX and NodeY values of the indexed node as the point at which the circle is centered. You can set the radius of the circle as per your choice. Using r=1 and picking an arbitrary index, I got:
Just one caveat: Make sure your axis are square. Otherwise, a circle might look like an ellipse. If you want to draw a circle around non-square axis, then you can modify the code to generate an ellipse instead.
I'm creating a figure with many polygons which can overlap in Matlab. I do not want borders on any of the shapes, only a translucent fill. I was able to get the first shape to obey this request using:
fill(xv,yv,'blue','FaceAlpha',0.1,'EdgeColor','None','LineStyle','none');hold on;
However, each subsequent shape which is drawn in the loop ignores this style, instead cycling through colored borders. I was able to use the set command to override the color cycle, but this still draws a border...I do not want any border. The border cannot be drawn at all because we are using the overlapping properties of the shapes, and the presence of any borders would perturb the nature of our simulation.
Here is the complete code:
for count = 1:92
x=randn*clustering;
y=randn*clustering;
angle=randn*360;
rectangle(width,height,x,y,angle);
end
function rectangle(w,h,x,y,angle)
%Define the rectangle
xv=[x x+w x+w x x];
yv=[y y y+h y+h y];
%Define the rotation transformation matrix
transform=[cos(angle) -sin(angle);sin(angle) cos(angle)];
%Define the translation to origin transform
xcenter=x+.5*w;
ycenter=y+.5*h;
%Perform translation to origin
tx=xv-xcenter;
ty=yv-ycenter;
%Perform rotation
rotated=transform*[tx;ty];
%Perform translation back to original location
xv=rotated(1,:)+xcenter;
yv=rotated(2,:)+ycenter;
%Plot result
figure(1);
plot(xv,yv);
fill(xv,yv,'blue','FaceAlpha',0.1);hold on;
axis square;
axis([-30 30 -30 30]);
I am trying to make a game in matlab where the user selects a shape and that shape translates and scales down a screen. The user then has to click on the shape and a point is added to their score. I was wondering how to make the program detect the users mouse click on the shape but end the program if they click on white space.
You can go along these lines. The following code basically uses:
fill to draw a polygonal shape;
ginput to get cursor position;
inpolygon to check if that position is inside the polygon.
Code:
xv = [ -3 3 3 -3]; %// x coords of polygon vertices. Arbitrary number
yv = [-5 -5 7 7]; %// y coords of polygon vertices. Same number as for x
fill(xv,yv,'b') %// draw polygon
axis([-10 10 -10 10])
[xp, yp] = ginput(1); %// get point coordinates
inside = inpolygon(xp,yp,xv,yv); %// is it inside?
if inside
%// it's inside. Do something accordingly
else
%// it's outside. Do something else
end