Axis coordinates to pixel coordinates? (Matlab)

2019-01-09 14:13发布

问题:

How can i convert the axis coordinates into pixel coordinates? I have a set of data which include the negative and floating values, i need to put all of the data into the image. But the pixel coordinates are all positive integer. how to solve the negative issue?

回答1:

You can pass vectors of coordinates to scatter.

x = [-1.2 -2.4 0.3 7];
y = [2    -1   1  -3];
scatter(x,y,'.');

If you need the image matrix,

h = figure();
scatter(x,y);
F = getframe(h);
img = F.cdata;

You can also use print to save the plot to a file (or simply export from figure window), then use imread to read the file.

There is also this set of m-files from the File Exchange, which are already very close to what you need.

Finally, here is a simple way to get what you want, within a specified precision:

precision = 10;        %# multiple of 10
mi = min(min(x),min(y));
x = x - mi;        %# subtract minimum to get rid of negative numbers
y = y - mi;
x = round(x*precision) + 1;    %# "move" decimal point, round to integer,
y = round(y*precision) + 1;    %# add 1 to index from 1
img = zeros(max(max(x),max(y)));    %# image will be square, doesn't have to be
x = uint32(x);
y = uint32(y);
ind = sub2ind(size(img),y,x);    %# use x,y or reverse arrays to flip image
img(ind) = 1;    %# could set intensity or RGB values in a loop instead

The "precision" parameter determines how many decimal places of the floating point values will be kept, and thus the resolution and accuracy of the image. The cast to uint32 might be unnecessary.

If you have a Nx3 matrix of RGB values for each of N points:

img = zeros(max(max(x),max(y)),max(max(x),max(y)),3);
for i=1:length(N)        %# N = length(x) = length(y)
    img(x(i),y(i),:) = rgb(i,:);
end


回答2:

From what I understand, you have a set of points representing an ellipse, and you would to draw them directly inside an image matrix (not just display them on screen).

For this, you can use the POLY2MASK function to convert the ellipse into a binary mask. Then by computing its perimeter, this will give us a binary mask representing only the pixels that constitute the ellipse, which is applied to the image to set the color of the pixels.

Consider the example below. I am using the function calculateEllipse.m from a previous question here on SO:

%# some image
I = imread('pout.tif');
sz = size(I);

%# ellipse we would like to draw directly on image matrix
[x,y] = calculateEllipse(100,50, 150,50, 30, 100);

%# lets show the image, and plot the ellipse (overlayed).
%# note how ellipse have floating point coordinates, 
%# and also have points outside the image boundary
figure, imshow(I)
hold on, plot(x,y, 'LineWidth',2)
axis([-50 250 -50 300]), axis on

%# create mask for image pixels inside the ellipse polygon
BW = poly2mask(x,y,sz(1),sz(2));

%# get the perimter of this mask
BW = bwperim(BW,8);

%# use the mask to index into image
II = I;
II(BW) = 255;
figure, imshow(II)

This should give you superior results to simply rounding the coordinates of x and y (plus it handles out-of-boundary points for us). Make sure to read the algorithm section of POLY2MASK to see how it works on a subpixel level.


EDIT:

if you are working with an RGB image (3D matrix), the same applies, you only need to change the last part where we use the binary mask :

%# color of the ellipse (red)
clr = [255 0 0];                %# assuming UINT8 image data type

%# use the mask to index into image
II = I;
z = false(size(BW));
II( cat(3,BW,z,z) ) = clr(1);   %# R channel
II( cat(3,z,BW,z) ) = clr(2);   %# G channel
II( cat(3,z,z,BW) ) = clr(3);   %# B channel
figure, imshow(II)

Here is yet another way:

%# use the mask to index into image
II = I;
BW_ind = bsxfun(@plus, find(BW), prod(sz(1:2)).*(0:2));
II(BW_ind) = repmat(clr, [size(BW_ind,1) 1]);
figure, imshow(II)