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

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

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)

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

My image is originally a DICOM image (so colored). But for my goal I can convert it to gray levels. That is not an issue. Thank you. Maura
The way that size() is defined when there are more array dimensions than outputs of size() would result in your "columns" variable containing values you probably did not expect. The fix is to use what I showed, adding the extra output to size()
DICOM images are not RGB. In fact ...
img = dicomread('T0_10x10_140.dcm'); size(img) ans = 768 1024
The x coordinate is the columns and the y coordinate is the rows. You have them reversed.
I would like someone to explain to me:
1. Matlab pixel indices convention. That is growing direction of row index and growing direction of column index
2. How to convert cartesian coordinates, centered in the image center, to pixel coordinates
Thank you in advance. maura.monville@gmail.com
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.
Very good explanation illustrated by simple examples. Thank you so much for clarifying my doubts.

Sign in to comment.

%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

It does not work. I get a horizontal straight line.
%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

Products

Asked:

on 4 Apr 2016

Commented:

on 14 Sep 2018

Community Treasure Hunt

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

Start Hunting!