Alternative to ginput for selecting data from an image?

I've got an image with pixels that are 0.1 units in x and 0,1 units in y. I want to have a user select some number 'n' points on that image and assign the x,y coordinates of those selections to a variable. I have tried to use "ginput" to do this, but there is one issue. When using ginput, if I click in the pixel (1.1, 3.2), for example, I might get values of (1.12034, 3.259034) when what I want is (1.1, 3.2). If I use the data cursor, it provides (1.1, 3.2) but I don't know how to automatically get those values into a variable.
I suppose I could round the coordinates down to the nearest 0.1, but the pixel size will not always be the same and I'd prefer to have a slightly more elegant solution. Is there another function similar to ginput that provides the x,y values of a point in the same way that the datacursor does?
Thanks!

Answers (2)

Sorry if I'm asking the obvious, but did you try round()?
[x,y] = ginput(1);
x = round(x, 1);
y = round(y, 1);

5 Comments

As I said, "I suppose I could round the coordinates down to the nearest 0.1, but the pixel size will not always be the same..." It is not guaranteed that the pixel size is 0.1. Sometimes it might be 0.01, or 0.05, or 27, so round() won't work.
I would like something which gives the same information that I would get by using the data cursor.
I don't understand what you're doing and why ginput() and round() are not enough. If you need subpixel accuracy, try zooming in on the image, though I'd have to check if the x,y given by ginput is from the original (unzoomed) coordinates, or from the zoomed coordinates in the frame.
If you just want to specify an x and a y in code, then do that and don't ask the user. Or else ask the user on your GUI to type in the coordinates or ask the user via the inputdlg() function.
Ok. Perhaps I am not explaining myself clearly enough.
First, I am not using a GUI.
I have a function where I am creating an Affine transformation matrix using two images. I need to choose four corresponding points from each image in order to solve for the Affine transformation from one image to the other. I would like to have the program prompt the user to click on the four points of each image and save the coordinates of those points.
When the image opens, it looks like this:
Using the data cursor on the point shown above provides [X,Y] = [-0.15, -0.08], which is what I want. However, I can't figure out how to assign those values to variables in my code. In other words, I would need to manually enter the values -0.15 and -0.08.
If a user uses ginput and clicks on that same point, however, they might get [-0.148972, -0.08330952] or [-0.15110238, -0.084001210].
Now, you suggested I use round(). The problem with this is that the pixels will not always be 0.01 units, so round(X,2) will not always accomplish what I need. Sometimes it will be round(X,1) or round(X,4). Sometimes the pixel size will not be a factor of 10 at all, but something like 0.3, in which case round() will not help at all.
ginput() will give you those values. If you want to see the values "live" as you mouse around, call impixelinfo() after you display it.
imshow(......
hp = impixelinfo();
h.Position = [left, top, width, height]. % You supply the actual numbers.
No, ginput() does not give me [X,Y] = [-0.15, -0.08], it gives me [X,Y] = [-0.148972, -0.08330952] or [X,Y] = [-0.15110238, -0.084001210] or whatever else depending on where exactly within the pixel I click. That is what I do not want.

Sign in to comment.

You need to use UpdateFcn. See this demo. This is all in my test3.m file:
function test3
sampleImage=[...
2 3 5 7 1
3 3 7 9 4
0 1 9 7 8]
imshow(sampleImage, [], 'InitialMagnification', 1600);
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0.5 1 .5]);
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
uiwait(msgbox('Please click on the data cursor icon on the toolbar, then click in the image and look in the command window.'));
dcm_obj = datacursormode(gcf)
set(dcm_obj,'UpdateFcn',@MyUpdateFunction)
function pos = MyUpdateFunction(~, event_obj)
% ~ Currently not used (empty)
% event_obj Object containing event data structure
% output_txt Data cursor text (string or cell array of strings)
pos = get(event_obj,'Position');
fprintf('You clicked at X = %.4f, Y = %.4f\n', pos(1), pos(2));

Categories

Asked:

on 26 Aug 2016

Answered:

on 27 Aug 2016

Community Treasure Hunt

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

Start Hunting!