exchange circle pixels in an image in matlab - arrays

All I want is to add a circle into an image of a radius and centre of my choice, however I DO NOT WANT to use plot COMMAND, I want a new output array which has my chosen image and circle on it.
here is my function
function [ out_image ] = draw_circle( in_image,x0,y0,r,value)
where in_image is the input image
x0 y0 he centre of circle and r the radius
value the intensity of image
this is my attempt which does not work
ang=0:pi/100:2*pi
x=r*cos(ang)+x0;
y=r*sin(ang)+y0;
cir=[x,y];
[j,k]=size(cir);
for cir=1:j
for cir=1:k
if cir(i,j)==0
out_image(i,j)=in_image(i,j);
end
end
end
imshow(out_image)
end

I'm pretty sure there are better ways, but following your approach, you might use the following code:
out_image = in_image;
cir = round([r*cos(ang)+x0;r*sin(ang)+y0]);
for i = 1:size(cir,2)
out_image(cir(1,i),cir(2,i),:) = 255;
end
Your for loops did not work the way you wrote them. Also, you should use round to get indices, and not floating point values. However, the circle is quite small (only 1 pixel), which might not be enough for large pictures. See example below. Also, you might need a finer discritization for large pictures, i.e. a larger number of elements in ang.
In case you want a larger linewidth, you can use
lw = 3; % Enter linewidth here
for i = 1:size(cir,2)
out_image(cir(1,i)+(-lw:lw),cir(2,i)+(-lw:lw),:) = 255;
end
EDIT: In case you don't see it. The circle is close to the top left corner.
The complete code for the function is:
function [ out_image ] = draw_circle( in_image,x0,y0,r,value,lw)
out_image = in_image;
ang = 0:pi/100:2*pi;
cir = round([r*cos(ang)+x0;r*sin(ang)+y0]);
for i = 1:size(cir,2)
out_image(cir(1,i)+(-lw:lw),cir(2,i)+(-lw:lw),:) = value;
end
imshow(out_image)
You can call it from command line with
draw_circle(in_image,100,200,50,0,3);
Note, I took the unused value as grayscale value.

Related

Widen a fibonacci flower using a for cycle

I was wondering in this example that I've used to practice for loops, I needed to change this code in order to change the image that looks like this, some basic golden angle plot:
to this example
phi = (sqrt(5)+1)/2;% Número áureo %Golden Number
golden_angle = 2*pi/phi;
max_angle = 10000;
theta = 1:golden_angle:max_angle;% ángulo %Angle
r = sqrt(theta);% radio %Radius
[x,y] = pol2cart(theta,r);% coordenadas polares a cartesianas %Polar to cartesian
figure
plot(x,y,'.','MarkerSize',10);axis off;
I know that the number next to 'MarkerSize' wides the flower petals, but I tried changing theta values in the array but with no particular result, only I’ve changed color but not the size. I also tried making these a for cycle, that creates circles as the golden flower petals, I think, but don't know how to implement it. But how to make them more and more small at the iteration goes?, and I think total number of petals is 2575.
for i = 1:10
%plot(x,y,'.',x(i),y(i),'.','MarkerSize',10*abs(y(i)),'MarkerFaceColor','g')
You can use scatter in place of plot: scatter allows to set the marker size as a parameter:
phi = (sqrt(5)+1)/2;% Número áureo %Golden Number
golden_angle = 2*pi/phi;
max_angle = 10000;
theta = 1:golden_angle:max_angle;% ángulo %Angle
r = sqrt(theta);% radio %Radius
marker_size = 10 * r / sqrt(max_angle); % new
[x,y] = pol2cart(theta,r);% coordenadas polares a cartesianas %Polar to cartesian
figure
scatter(x,y,marker_size, 'fill'); axis off; % new: scatter
marker_size data look good on table, increasing from 0 to 10 with theta.
However, on my Matlab (R2013b), the rendering is very gross.

MATLAB Add Mouse Click Coordinate to Matrix?

I am creating an image processing project in matlab. I want to get 5 coordinates from image with mouse and save them to a matrix. When I run project, I click only once but the matrix is taking same coordinates. How can I fix it ?
function ImageClickCallback ( objectHandle , eventData )
array = 3:2;
for i = 1:3
axesHandle = get(objectHandle,'Parent');
coordinates = get(axesHandle,'CurrentPoint');
coordinates = coordinates(1,1:2);
array(i,1) = coordinates(1);
array(i,2) = coordinates(2);
end
disp(array);
For example when I click a point on image, I am taking this result. I can't select another points.
99.3806 37.1915
99.3806 37.1915
99.3806 37.1915
A much safer alternative would be to use ginput, with which you can select a variable number of points and store their coordinates easily. You don't need a loop; the coordinates are stored once all the points are selected.
Here is a simple example:
clear
clc
close all
A = imread('peppers.png');
imshow(A,[]);
hold on
%// Number of points
N = 5;
array = zeros(N,2);
%// Use a for loop and plot 1 point at a time.
for k = 1:N
[array(k,1),array(k,2)] = ginput(1);
%// Display the points
scatter(array(k,1),array(k,2),60,'k','filled')
end
Sample output for array:
123.0000 87.0000
95.0000 206.0000
256.0000 85.0000
236.0000 253.0000
395.0000 117.0000
And the image with the points displayed:
Therefore, you could would look like this:
function ImageClickCallback ( objectHandle , eventData )
array = zeros(3,2);
[array(:,1),array(:,2)] = ginput(3);

How to save part of image in arrays or matrices in Matlab

I am developing a project of detecting vehicles' headlights in night scene. I am working on a demo on MATLAB. My problem is that I need to find region of interest (ROI) to get low computing requirement. My solution is calculating total intensity per row and if the row's intensity is below threshold, it is blacked.
[rows col] = size(img1);
sumValue=[];
sum1 = sum(sum(img1)/(rows*col));
for a=1:1:rows
sumValue = sum(img1(a,:))/col;
if (sumValue <sum1+40)
img1(a,:)=0;
end
end
And here is the result:
Now i want to save the bright parts of image in arrays or matrices so that i can delete the small bright parts and keep only large part. If anyone has any idea, plz give me some suggestions.
I'm sure this could be optimised a bit more.
new_im = zeros(size(im));
% Loop through each column
for c=1:1:size(im,2)
column = im(:,c);
% The first non-zero value in each column will be the top of the window
upper_candidates = find(column>0);
top = upper_candidates(1);
% The first zero value after that will be your lower boundary
lower_candidates = find(column(top:end) == 0);
bottom = lower_candidates(1);
% Insert each column into the new image
new_im = im(top:bottom,c);
end

Plotting from a 2D Array Using a Loop

This seems like a trivial problem, though I've been hitting myself over the head with it for too long.
This doesn't even plot just the (0,0) -- I can't seem to find much about plotting from arrays -- rather just matrix plots (and only columns at that).
The data is properly in these arrays, I just need to make plots! Doesn't seem so complicated. I don't even need separate colors for the different sets...just all one big scatter plot.
Any suggestions?
pdf(mypath)
# Plot first point
plot(0,0, col = "blue", type = "n", xlab="PES", ylab=""%eff")
#Loop to Plot remaining points
for(rows in 1:nrowX)
{
for(cols in 1:ncolX)
{
points(X[rows,cols],Y[rows,cols], col = "blue", type = "p")
}
}
dev.off
I have also tried using plot.new() to have an empty plot...but no such luck.
SOLUTION!!
Turns out I'm just a fool. Code is acurate and the suggestions below do indeed work.
R happened to be open in another tab and since it was open, never let go of the plot (why? I don't know). As soon as it was closed, the plot appeared. Now I can get my plot again and again...
Thanks to everyone who tried helping a problem that wasn't a problem!
I like this place already!
When you set type = "n", the plot function will not plot anything at all. It is used to set up a basis for the rest of the plot (like axis labels, limits etc). That is why the first point at (0, 0) does not show up.
The rest of the points are probably outside the range. Use xlim and ylim to set up the ranges properly. I'm going to assume X and Y have the same size and dimension. Try this:
pdf(mypath)
# Set up the plot
plot(0, type="n", xlab="PES", ylab="%eff", xlim=range(X), ylim=range(y))
# Now plot
points(X,Y, col="blue")
dev.off
Of course you could let the plot function take care of the limits for you:
pdf(mypath)
plot(X, Y, xlab="PES", ylab="%eff")
dev.off()
Your initial plot will set up the coordinates, but since you only give it one point it does not know how much room to leave around the 0,0 point (so it does not leave very much). I expect that the rest of your points fall outside of that range which is why they don't show up on the plot (you can use par("usr") to see what the extents are).
When you create the initial plot you should include xlim and ylim arguments so that the plot includes the area where the new points will be added, something like:
plot(0,0, type='n', xlim=range(X), ylim=range(Y))
You may also be interested in the matplot function which will take a matrix as either or both the x and/or y argument and plot accordingly.
Edit
The following works for me:
X <- matrix( runif(390), nrow=10 )
Y <- matrix( rnorm(390), nrow=10 )
plot(0,0, col = "blue", type = "n", xlab="PES", ylab="%eff",
xlim=range(X), ylim=range(Y))
#Loop to Plot remaining points
for(rows in 1:nrow(X))
{
for(cols in 1:ncol(X))
{
points(X[rows,cols],Y[rows,cols], col = "blue", type = "p")
}
}
I did remove an extra " from the ylab, was that your problem?
But
plot(X,Y)
also worked without the looping.
Check with just the console to see if it works before worrying about sending to a pdf file. If this has not fixed it yet, we still need more details.

Matlab - Cropping 2d image maps in a loop and storing in a single variable

I have a code to crop connected components of input image, input, by finding the boundary conditions from a binary image's labelled map, labelledmap ([labelledmap, labelcount] = bwlabel(hvedged, 8);)
I'm new to matlab so this might sound stupid..
The problem is, I am unable to store different cropped images in the same variable, Because matlab seems to merge the ends of the already existing image and the new cropped image, i.e, it is storing the complete map between the two cropped images, the way i see it :/
This is the output Using different variables for storing cropped image (the kind of output i want)
Output Using different variables for storing cropped image
This is the output i'm getting by storing the cropped image in the same variable(not helpful)
Output when storing cropped image in the same varible
I tried using an array of size equal to total number of labels produced but it's giving the same result.. also i tried clearvars for clearing the output token image, ltoken, after every iteration of the loop but it's not helping
So, is there any possible way to display individual cropped images.. also the number of cropped images might be in thousands so i want to use a loop to code their cropping mechanism
here is a part of the code attached.. thanks in advance ;)
for h=1:labelcount
for i=1:r
for j=1:c
if labelledmap(i,j)==h
if i<ltop
ltop=i;
end
if i>lbottom
lbottom=i;
end
if j<lleft
lleft=j;
end
if j>lright
lright=j;
end
end
end
end
if ltop>5
ltop=ltop-5;
end
if lbottom<r-5
lbottom=lbottom+5;
end
if lleft>5
lleft=lleft-5;
end
if lright<c-5
lright=lright+5;
end
lwidth=lright-lleft;
lheight=lbottom-ltop;
ltoken=imcrop(input,[lleft ltop lwidth lheight]);
figure('Name', 'Cropped Token'), imshow(ltoken);
clearvars ltoken;
end
you need to initialize ltop lbottom lleft and lright for each iteration of label h. I think this is the reason why you get the cropped images "glued" together.
It is EXTREMELY inefficient to go through all the pixels for each and every one of your labels. Especially when you are expected to have many labels.
Use regionprops to get the 'BoundingBox' property for each label.
Here's an example
st = regionprops( labelledmap, 'BoundingBox' );
imlist = cell( 1, numel(st) ); % pre-allocate
for ii=1:numel(st)
r = st(ii).BoundingBox;
% I understand you want to increase the BB by 5 pixels at each side:
r(1:2) = r(1:2) - 5; % start point moves -5
r(3:4) = r(3:4) + 10; % width and height increases by 10
imlist{ii} = imcrop( input, r );
end
I'm still a bit in shock by your code that explicitly loops through all pixels just for finding the bouding box. This is NOT the matlab way of doing things.
If you insist on NOT using regionprops here's a more Matlab-ish way of finding the ii-th bounding box:
imsk = (labeledmap == ii); % create a binary map with True for ii-th region
xFlat = any(imsk,1); % "flattening" imsk on the x-axis
lleft = find( xFlat, 1, 'first' );
lright = find( xFlat, 1, 'last' );
yFlat = any(imsk, 2);
ltop = find( yFlat, 1, 'first' );
lbottom = find( yFlat, 1, 'last' );
No loops at all over image coordinates.

Resources