Reputation: 9796
I want to display a series of images to a user. For each image request input from the user in the form of a mouse click on the image. Store the coordinates of each click in a matrix. Thus, in end having a matrix of dimension num_images x 2.
function main()
clc;
global agent_pos;
....
for i=1:numel(img_names),
imname = [ path_img img_names{i}];
im0 = imread(imname);
imageHandle =imshow(im0);%_____________displays the image
set(gcf,'units','normalized','outerposition',[0 0 1 1])
set(imageHandle,'ButtonDownFcn',@ImageClickCallback);
uiwait(gcf);
end
end
function coordinates=ImageClickCallback ( objectHandle , eventData )
axesHandle = get(objectHandle,'Parent');
coordinates = get(axesHandle,'CurrentPoint');
coordinates = coordinates(1,1:2);
global agent_pos;
agent_pos=[agent_pos;coordinates]; %___ add these coordinates for each image
uiresume;
end
What I want to do is to zoom into a part of the picture using the GUI
and click on the image. When I do so, matlab
should record the pixel points' location with respect to the unzoomed image. Also, once the select the zoom location in the first image. It should the same in coming up ones.
When I try do the zoom through GUI
in the first image now, and then change back the pointer to a cursor, it somehow stops and doesn't either record my click or go to the next image.
Warning: figure JavaFrame property will be obsoleted in a future release. For more information see the JavaFrame resource on the MathWorks web site.
I tried to use imtools instead of imshow, but it show below warning with opening 2 images at a time and not record the clicks.
In main at 20 java.lang.NullPointerException at com.mathworks.hg.peer.FigureFrameProxy.setMaximized(FigureFrameProxy.java:302) at com.mathworks.hg.peer.FigureMediator.setMaximized(FigureMediator.java:468) at com.mathworks.hg.peer.FigurePeer.doSetMaximized(FigurePeer.java:3414) at com.mathworks.hg.peer.FigurePeer$26.run(FigurePeer.java:3403) at com.mathworks.hg.util.HGPeerQueue$HGPeerRunnablesRunner.runit(HGPeerQueue.java:294) at com.mathworks.hg.util.HGPeerQueue$HGPeerRunnablesRunner.runNotThese(HGPeerQueue.java:326) at com.mathworks.hg.util.HGPeerQueue$HGPeerRunnablesRunner.run(HGPeerQueue.java:342) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access$200(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) Operation terminated by user during uiwait (line 81)
EDIT 1: Complete code:
function main()
clc;
global agent_pos;
h = figure(1); % Initiate figure with a specific number for easy handling
set(h,'WindowButtonDownFcn',@ImageClickCallback);
agent_pos=[];
path_img='.\image_files_resized\'; %__________image files path
path_posmap='.\pos_maps\';%_________stores positions of agents
NumOfImages = length(dir(path_img)) - 2;
w = dir(path_img);
img_names={}; %________stores names of all images
for i=3:NumOfImages+2,
img_names{i-2} = w(i).name;
end
for ii=1:numel(img_names),
% Get the XLim and YLim from previous imshow session
if ii > 1
XLim = h.CurrentAxes.XLim;
YLim = h.CurrentAxes.YLim;
end
imname = [ path_img img_names{ii}];
im0 = imread(imname);
figure(1);
imageHandle =imshow(im0);%_____________displays the image
[ht,wid,c]=size(im0);
if ii==1,
pause(0.00001);
frame_h = get(handle(gcf),'JavaFrame');
set(frame_h,'Maximized',1);
hold on;
[x,y]=getPrevAgents();
plot(x,y,'o','color','green')
end
xlabel(img_names{ii});
% Set the zoom level and location the same with previous imshow session
if ii > 1
set(h.CurrentAxes, 'XLim', XLim)
set(h.CurrentAxes, 'YLim', YLim)
end
uiwait(gcf);
end
filename = datestr(now,'mm_dd-HH_MM_SS');
csvwrite(strcat(path_posmap,filename,'.csv'),agent_pos);
close(gcf);
plot_posagents();
d = dir(strcat(path_posmap,'*.csv'));
numfiles = length(d);
disp(sprintf('Only %d files done..',length(d)));
end
function coordinates = ImageClickCallback ( objectHandle , eventData )
global agent_pos;
coordinates = get(objectHandle,'CurrentPoint');
coordinates = coordinates(1, 1:2);
agent_pos = [agent_pos;coordinates];
uiresume;
end
ERROR:
Invalid or deleted object.
Error in main_new (line 18)
XLim = h.CurrentAxes.XLim;
Upvotes: 3
Views: 202
Reputation: 2192
In MATLAB, zoom is implemented through setting the XLim
and YLim
of the current axes. So to get the zoom info, you simply need to acquire these properties from the axes. If all your images are of the same size, you won't need to perform any calculation to get the zoom factor and zoom location to be applied to different images. Otherwise, zoom factor will be (XLim[2] - XLim[1])/size(img,2)
. CurrentPoint
is a property of the figure but not its axes. So in your code, you won't get any coordinates. The following code should work properly if you first click on zoom button, zoom in or out, click the zoom off then go the position you like and click. If you click the mouse button while the zoom is still on, the 'WindowsButtondownFcn'
will be that of the zoom object and won't do what you want it to do.
function main()
global agent_pos;
h = figure(1); % Initiate figure with a specific number for easy handling
set(h,'WindowButtonDownFcn',@ImageClickCallback);
for ii = 1:numel(img_names)
% Get the XLim and YLim from previous imshow session
if ii > 1
% for version 2014b and later
% XLim = h.CurrentAxes.XLim;
% YLim = h.CurrentAxes.YLim;
CurrentAxes = get(h, 'CurrentAxes');
XLim = get(CurrentAxes, 'XLim');
YLim = get(CurrentAxes, 'YLim');
end
imname = [ path_img img_names{ii}];
figure(1) % To ensure we're always staying on the same figure
imshow(imname)
% Set the zoom level and location the same with previous imshow session
if ii > 1
% for version 2014b and later
% set(h.CurrentAxes, 'XLim', XLim)
% set(h.CurrentAxes, 'YLim', YLim)
CurrentAxes = get(h, 'CurrentAxes');
set(CurrentAxes, 'XLim', XLim)
set(CurrentAxes, 'YLim', YLim)
end
uiwait(gcf);
end
end
function coordinates = ImageClickCallback ( objectHandle , eventData )
global agent_pos;
coordinates = get(objectHandle,'CurrentPoint');
coordinates = coordinates(1, 1:2);
agent_pos = [agent_pos;coordinates];
uiresume;
end
It should be noted that since MATLAB 2014b, there's a major change on how graphics handle is implemented. see here
And to ensure your plotting command doesn't change the zoom setting, you can add these
if ii==1,
CurrentAxes = get(h, 'CurrentAxes');
XLim = get(CurrentAxes, 'XLim');
YLim = get(CurrentAxes, 'YLim');
% your code here
pause(0.00001);
...
plot(x,y,'o','color','green')
set(CurrentAxes, 'XLim', XLim)
set(CurrentAxes, 'YLim', YLim)
end
Upvotes: 3