How to convert from cartesian coordinates to pixel indices on a 2D image

21 views (last 30 days)
Please take a look at the attached MatLab script. The goal is to plot the image intensity across a diameter passing through the image center and making an arbitrary angle 'phi' with the Cartesian x_axis. No averaging over image intensities. I can calculate the pixel indices of one end of the diameter as follows:
[rows columns] = size(img);
xmid = ceil(rows/2);
ymid = ceil(columns/2);
phi = 30*pi/180;
xs = xmid + round(ceil(radius * cos(phi)))
ys = ymid + round(ceil(radius * sin(phi)))
However, I am unable to get the indices of the other diameter end. Geometrically I would do:
xf = xmid + round(ceil(radius * cos(phi + pi)))
yf = ymid + round(ceil(radius * sin(phi + pi)))
The last two formulae do not generate the righ pixel indices of the other diameter end.
I tried the method indicated in an on-line example using function 'axes2pix' but MatLab issued an error upon getting XData and YData ... God knows why ...
I would greatly appreciate some help at computing correctly the pixel indices of a diameter passing through the 2D image center at an arbitrary angle 'phi'.
Thank you in advance.
Maura
**** Please reply to *maura.monville@gmail.com*
  1 Comment
win hlaing
win hlaing on 14 Sep 2018
xf = xmid + round(ceil(radius * cos(phi + pi))) yf = ymid - round(ceil(radius * sin(phi + pi)))
you just have to change + sign for y axis.. coz on paper cartesian plane for x and y and computer base pixel plane are not the same. For computer, y axis is changing. That why you have to subtract your r*sin theta from your ymid.

Sign in to comment.

Answers (2)

Walter Roberson
Walter Roberson on 4 Apr 2016
You have
[rows columns] = size(img);
Is your image RGB? If so then that line is wrong and you need
[rows, columns, ~] = size(img);
  8 Comments
Walter Roberson
Walter Roberson on 5 Apr 2016
Take a piece of paper. Label it with increasing coordinates downwards along the left, and label it with increasing coordinates towards the right on the bottom. The downwards coordinates are the MATLAB row numbers, the first index into an array. The rightwards coordinates are the MATLAB column numbers, the second index into an array. And just like traditional graph paper, up/down is the Y coordinate and left/right is the X coordinate. So the Y coordinate is row number, and the X coordinate is column number.
However, the origin for arrays is at the top left, with the numbers increasing downwards (and no negative numbers), so this is like a mirror image of the First Quarter, mirrored around Y = 0.
To allow the Y coordinate to grow up from the bottom left, MATLAB offers an axes property 'YDIR' which can be set to 'Reverse' to reverse the way an image would normally appear.
However, YDIR 'Reverse' would also affect normal graphics operations that have Y growing upwards. The mechanism to deal simultaneously with normal First Quadrant graphics and with image numbering being from the other direction, is to flipud() the image before displaying it.
foo = ones(20,20); foo(1,1) = 2; image(foo); colormap(gray(2));
This will display the white square at the top left, following array convention, and YDIR will be automatically set to Reverse
However, if you plot() first and "hold on" then YDIR will be 'Normal' and the image will turn over:
plot([1 25],[1 25],'r');hold on; image(foo); colormap(gray(2));
I do not recall which way up imshow() uses by default.
Maura Monville
Maura Monville on 5 Apr 2016
Very good explanation illustrated by simple examples. Thank you so much for clarifying my doubts.

Sign in to comment.


Kuifeng
Kuifeng on 4 Apr 2016
%I would suggest use the 'ceil' and 'floor' combination for pixels
xs = xmid + round(ceil(radius * cos(phi)));
ys = ymid + round(floor(radius * sin(phi)));
xf = xmid + round(floor(radius * cos(phi + pi)));
yf = ymid + round(ceil(radius * sin(phi + pi)));
  2 Comments
Kuifeng
Kuifeng on 5 Apr 2016
%for example,
xmid = 300;
ymid = 300;
phi = 30*pi/180;
radius = 100;
xs = xmid + round(ceil(radius * cos(phi)));
ys = ymid + round(floor(radius * sin(phi)));
xf = xmid + round(floor(radius * cos(phi + pi)));
yf = ymid + round(ceil(radius * sin(phi + pi)));
plot(radius.*cos(0:0.01:2*pi)+xmid, radius.*sin(0:0.01:2*pi)+ymid,'b');
hold on,
plot([xs xf], [ys yf], 'r*-');
axis equal

Sign in to comment.

Categories

Find more on Programming in Help Center and File Exchange

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!