2015-10-17 45 views
3

我想要向用戶顯示一系列圖像。對於來自用戶的每個圖像請求輸入,以鼠標的形式點擊圖像。將每次點擊的座標存儲在矩陣中。因此,在末端具有尺寸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 

我想要做的就是使用GUI放大到圖片的一部分,然後在圖像上。當我這樣做時,matlab應記錄像素點相對於未放大圖像的位置。另外,一旦選擇第一張圖像中的變焦位置。它應該在即將到來的相同。


當我試圖通過GUI第一圖像做縮放現在,然後將指針變回一個光標,它在某種程度上停止工作,也不記錄我的點擊或進入下一個圖像。 警告:圖形JavaFrame屬性將在未來版本中廢棄。有關更多信息,請參閱MathWorks網站上的JavaFrame資源。

我試圖使用imtools而不是imshow,但它顯示下面的警告,一次打開2個圖像而不記錄點擊。

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: 完整代碼:

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; 

回答

3

在MATLAB中,變焦通過設置XLim和當前軸YLim實現。所以要獲取縮放信息,您只需從軸上獲取這些屬性即可。如果所有圖像尺寸相同,則不需要執行任何計算即可將縮放比例和縮放位置應用於不同的圖像。否則,縮放因子將爲(XLim[2] - XLim[1])/size(img,2)CurrentPoint是圖的屬性,但不是其軸。所以在你的代碼中,你不會得到任何座標。如果您首先點擊縮放按鈕,放大或縮小,單擊縮放,然後轉到您喜歡的位置並單擊,以下代碼應該可以正常工作。如果您在變焦仍處於開啓狀態時單擊鼠標按鈕,則'WindowsButtondownFcn'將是縮放對象的那個,並且不會執行您想要的操作。

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 

應該指出的是,自MATLAB 2014b以來,圖形手柄的實現方式發生了重大變化。看到here

並確保您的繪圖命令不改變變焦設置,您可以添加這些

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 
+0

請檢查編輯1. –

+0

見更新的答案。圖柄結構在MATLAB 2014b中經歷了重大變化,並且使得許多代碼在不同版本之間不能一致地工作。事實上,如果我在2014a上運行我的代碼,我會看到相同的錯誤消息。現在更新的代碼應該在2014a上運行(理論上也是早期版本)。 – user3667217

+0

它適合你嗎? – user3667217