How can i create circles in a image ....not using plot function? - image

basically, i am supposed to create a image with circles and lines... not using plot function.
because the final output is to pop out by imshow().or image().or imagesc()...
and the created image will contiune the color processing.

The simplest way is to draw it as usual, then use getframe to grab an image of the figure.
EDIT: I don't have time for much detail, but look at the following:
line: http://www.mathworks.co.uk/help/techdoc/ref/line.html
circle: http://www.mathworks.com/matlabcentral/fileexchange/2876
axis properties: http://www.mathworks.co.uk/help/techdoc/ref/axes_props.html (You may want to set 'Visible', 'off', 'Position', [0 0 1 1], 'DataAspectRatio', [1 1 1])
getframe: http://www.mathworks.co.uk/help/techdoc/ref/getframe.html
The MATLAB help is really very useful.

If you are trying to draw lines and circles directly on a raster image (matrix of pixels), then check out the Bresenham line-drawing algorithm and its variants for circles.
I am sure you can find existing implementations for them on FEX
Another possibility is to show the image (IMSHOW, IMAGESC, ..), use the plotting functions as usual (PLOT, LINE, ...), then grab the displayed figure as image again using GETFRAME as Nzbuu suggested.

Use the matlab function "rectangle" and specify the 'Curvature" parameter to one. i.e.
rectangle('Position',[0 0 100 100],'Curvature',[1 1])
This is obviously counter intuitive, but in Matlab, rectangle is the function you use to draw ellipses and circles.
Here is the appropriate mathworks doc:
http://www.mathworks.com/help/techdoc/ref/rectangle.html

Related

How to draw a polygon in matlab in a 2D matrix

I have the follow code in matlab which is supposed to draw a polygon on a image (has to be a 2d image, be just a patch).
numCorners=8;
dotPos=[];
for rr=1:numCorners
dotPos(end+1)=(cos(rr/numCorners*2*pi))*100;
dotPos(end+1)=(sin(rr/numCorners*2*pi))*100;
end
BaseIm=zeros(1000,1000);
dotpos=[500,500];
imageMatrix =drawpolygon(BaseIm, dotPos, 1); or how else do draw a white polygon here?
imshow(imageMatrix);
This doesn't work as drawpolygon does not appear to exist in this way any idea how to do this?
Note that the resulting data must be an image of equal size of baseIM and must be an array of doubles (ints can be converted) as this is test data for another algorithm.
I have since found the inpolygon(xi,yi,xv,yv); function which I could combine with a for loop if I knew how to properly call it.
If you just need to plot two polygons, you can use the fill function.
t=0:2*pi;
x=cos(t)*2;
y=sin(t)*2
fill(x,y,'r')
hold on
fill(x/2,y/2,'g')
As an alternative, you can use the patch function:
figure
t=0:2*pi;
x=cos(t)*2;
y=sin(t)*2
patch(x,y,'c')
hold on
patch(x/2,y/2,'k')
Edit
The fill and patch functions allow to add polygons also over an actual image too.
% Load an image on the axes
imshow('Jupiter_New_Horizons.jpg')
hold on
% Get the axis limits (just to center the polygons
x_lim=get(gca,'xlim')
y_lim=get(gca,'ylim')
% Create the polygon's coords
t=0:2*pi;
x=cos(t)*50+x_lim(2)/2;
y=sin(t)*50+y_lim(2)/2
% Add the two polygons to the image
f1_h=fill(x,y,'r')
hold on
f1_h=fill(x/2,y/2,'g')
Hope this helps.

How to find the centroid of different sections of an image?

I have an image that I want to divide in three parts and find the centroid of the parts separately and display them on original image, I used blkproc for dividing the image in [1 3] grids, but can't display the centroids. Here is the code I wrote,
i=imread('F:\line3.jpg');
i2=rgb2gray(i);
bw=im2bw(i2);
imshow(bw)
fun=#(x) regionprops(x,'centroid');
b=blkproc(bw,[1 3],fun);
But I can't get to display the centroids, as well as get their values. Any help will be much appreciated.
You can just use the plot command to plot over the top of the image.
Whatever you [X,Y] centroid coordinates are, say cx(1:3) and cy(1:3)
numCentroids is the number of centroids you are plotting.
hold on;
for ii = 1:length(numCentroids)
plot(cx(ii),cy(ii),'Marker','s','MarkerSize',10,'MarkerFaceColor','r','MarkerEdgeColor','k')
end
If you wanted to write more elegant code, you could run the plot command once across all your centroids and then make the line style type invisible. The answer I supplied should work though.
Here's an example image with made up centroids.
Strong recommendation - use blockproc instead of blkproc. It is better designed and easier to use.
Now, first of all, the second input to blockproc is the blocksize and not the grid size. So if you want to divide your image into [1 3] grid, which I understand as a single row of three blocks, then you should set your blocksize as:
blocksize = [size(i,1) ceil(size(i,2)/3)];
The second thing is to turn off the 'TrimBorder' parameter in blockproc. The code would look something like:
fun=#(x) regionprops(x,'centroid');
blocksize = [size(i,1) ceil(size(i,2)/3)];
b=blockproc(bw,blocksize,fun,'TrimBorder',false);
One minor thing - I would recommend not using the variable name 'i'. By default it represents the imaginary number i = sqrt(-1); in Matlab.

Function to map an image to 3D point by point

I am trying to map my image point by point to 3 dimensional space.
For example, if my original image has intensity of 100 at location X, I want to plot this point in 3D location Y with intensity of 100. I want to repeat this steps for every point/pixel, and get a final image. My biggest problem is that I want to do it point by point.
I appreciate any comments or advice. Thank you.
=======================
p.s.
As I was writing this question, I just came up with an idea. I know how to print 'whole' image into certain location/shape in 3D by using warp() function. Instead of using my whole image as an argument to warp function, if I give one point intensity value and one 3D point as arguments for warp function, and repeat this steps for every image point, will I get a descent looking final image in 3D? If there is a better function to use, please let me know.
Sounds like you are looking for scatter3:
I = imread('cameraman.tif');
[x y]=meshgrid(1:size(I,1), 1:size(I,2));
scatter3(x(:),y(:),I(:),15,I(:),'filled');
axis tight; colormap gray
And this is what you get (after some changes to view point):
PS,
I used a single scatter3 command to plot all the points at once. You may (I have no idea why you would like to do so) do it one by one
figure;
for ii=1:numel(x)
scatter( x(ii), y(ii), I(ii), 15, I(ii), 'filled');
hold on; % need this!
end
axis tight; colormap gray;

What is this effect called and how does one achieve it using Matlab?

I am trying to generate the following "effect" from a basic shape in MATLAB:
But I don't even know how this process is called. Let's say I have an image containing the brown shape, what I want is generate the contours outside of it, that get smoother as they get bigger.
Is there either a name for this effect, a function to do this in MATLAB or an algorithm that does it from scratch?
thanks
I think you are looking for bwdist.
The image you are displaying looks like the positive part of a distance function from the boundary of your shape. You can perform this easily in Matlab using the examples on the aforementioned manual page.
Try this:
I = imread('brown_image.png');
I_bw = (rgb2gray(I) > 0); % or whatever, just so I_bw is 1 in the 'brown' region
r = 10;
se1 = strel('disk', r);
se2 = strel('disk', r-1);
imshow(imdilate(I_bw, se1) - imdilate(I_bw, se2))
Requires image processing toolbox, but the basic idea is to dilate the image twice with dilation elements that differ by 1 (or however thick you want the contours to be) and subtract the result of the smaller one from the bigger one. You could then color them however you want.

How to extract a linear slice from an image in OpenCV / EMGU

I have an image and two points,
and I want to read the pixels between these two points,
and resample them into a small 1x40 array.
I'm using EMGU which is a C# wrapper for OpenCV.
thanks,
SW
What you are looking for is Bresenham's line algorithm. It will allow you to get the points in the pixel array that best approximate a straight line. The Wikipedia link also contains psuedo code to get you started.
Emgu CV includes method in the Image class for sampling color along a line called Sample.
Refer to the manual for the definition. Here's the link to Image.Sample in version 2.3.0.
You will still have to re-sample/interpolate the points in array returned from Sample to end up with a 40 element array. Since there are a number of ways to re-sample, I'll suggest you look to other questions for that.
Rotate and crop
I'd first try to do it like this:
calculate rotation matrix with (GetRotationMatrix2D)
warp the image so that this line is horisontal (WarpAffine)
calculate new positions of two of your points (you can use Transform)
get image rectangle of suitable width and 1 px high (GetRectSubPix)
Interpolation here and there may affect the results, but you have to interpolate anyway. You may consider cropping the image before rotation.
Iterate over the 8-connected pixels of the line
Otherwise you may use the line iterator to iterate over the pixels between two points. See documentation for InitLineIterator (Sorry, the link is to the Python version of OpenCV, I've never heard of EMGU). I suppose that in this case you iterate over pixels of a line which was not antialiased. But this should be much faster.
Interpolate manually
Finally, you may convert the image to an array, calculate which elements the line is passing through and subsample and interpolate manually.

Resources