2015-09-07 42 views
2

我正在處理一個代碼,以獲取用戶輸入的多個可拖動矩形的位置。代碼工作得很好。但是,按下按鈕後,代碼不會向前移動,直到您再繪製一個矩形。我相信這個問題是pos = uint32(wait(h));語句無限期地等待另一個位置,並且在繪製另一個矩形之後才考慮按鈕句柄。我需要wait (h)聲明作爲getposition函數不適合我。我非常感謝您提供的任何幫助,以下是我的代碼的一部分。多個可拖動矩形matlab:多餘矩形

代碼:

im_des=rgb2gray('image_name.jpg'); 
ButtonHandle = uicontrol('style','push','String', 'STOP',... 
'callback','set(gcbo,''userdata'',1,''string'',''DONE!'')', ... 
'userdata',0) ; 

while(1) 
    if get(ButtonHandle,'userdata') 
     break ; 
    end 

    h = imrect; 
    pos = uint32(wait(h)); 

    if ~isempty(pos)  
     rectangle('Position', pos, 'LineWidth',1, 'EdgeColor','k'); 
     for i=1:4 
     counter=counter+1; 
     array (counter) = pos(i); 
     end 
     delete(h); 
    end 
end 

回答

1

我已經想通了,之所以需要按下停止按鈕後繪製一個矩形外,我已經找到了幾個可能的解決方案來解決這個問題。

簡而言之,問題是...... MatLab比你快。

在更多的話,這是發生什麼事,一步一步:

讓我們假設你想畫只有一個矩形,然後按下「停止」按鈕來停止繪製。

while循環開頭的if語句中的條件未驗證(尚未按下按鈕),因此循環繼續。

if get(ButtonHandle,'userdata') 
    break ; 
end 

imrect語句然後執行

h = imrect; 

它開始矩形繪製過程:可以繪製矩形,移動它,調整它的大小ANS等。

一旦你開始畫下一個語句執行

pos = uint32(wait(h)); 

wait功能塊MATLAB命令行,直到矩形您double-click從繪圖模式

如果您已經退出繪製一個有效的矩形,下一個語句繪製實際的矩形,將矩形的位置存儲在「數組」中,並刪除handleimrect對象

if ~isempty(pos)  
    rectangle('Position', pos, 'LineWidth',1, 'EdgeColor','k'); 
    for i=1:4 
     counter=counter+1; 
     array (counter) = pos(i); 
    end 
    delete(h); 
end 

此時您決定「停止」添加矩形並按下「停止」按鈕。

以下是MatLab比您快的點。

當您移動muose的光標到達按鈕時,腳本的執行會繼續,並且while循環的新迭代開始。

又是第一個語句執行

if get(ButtonHandle,'userdata') 

,如果你沒有這麼快(你不能),以達到「停止」按鈕,並在新的迭代開始前推,在if條件未驗證,因此 的imrect順序執行

h = imrect; 
pos = uint32(wait(h)); 

爲你的意圖是提請另一個矩形。

這是「seeem」在按下「Stop」按鈕後需要實際停止腳本的「附加」矩形。

雖然MATLAB命令行由wait功能受阻,callback聽者不是,所以可以推pusshbutton和userdata的值被設置爲1 儘管如此,拉拔處理已被激活。

因此,您需要繪製「附加」矩形,雙擊退出wait,以便可以開始「while循環的迭代器」。

此時,最終將驗證if條件,並且break語句會停止執行while循環。

這是發生了什麼事。

我發現了兩種可能的解決方案:第一種可以讓您的腳本「幾乎」保持原樣,第二種意味着歪曲GUI概念。

第一種解決方案可以讓您...... MatLab更快。

如果你調用wait(例如pause(3))後插入pause聲明,你將有3秒內達到一個新的迭代開始前,按下「停止」。

這使得車callback設置userdata設置爲1,使if條件在while循環的開始被驗證停止腳本的executin無需作出任何附加矩形。

第二種解決方案在於改變GUI的行爲:

您可以刪除while循環和改變pushbutton callback因此,它需要調用imrect的關心和繪製矩形(在實際應用中,你必須移動 代碼在pushbutton cllbackwhile循環內

這樣的GUI的行爲將是:要添加一個矩形內的任何時候,你推pushbutton

在此之後,您可以找到兩種解決方案的腳本。

通知,我做了一些額外的修改你的額外的代碼,以使其運行:

我已經刪除了uint32 cast:具有中軸線不是一個圖片,默認axes限值[ 0 1], 如果轉換posunsigned 32-bit integer,POS將成爲[0 1 0 0]

而且我已經刪除了for循環存儲posarray:它實際上沒有必要。

溶液#1

% Commented since in the code excerpt is not used 
% im_des=rgb2gray('pdb_img_1.jpg'); 
ButtonHandle = uicontrol('style','push','String', 'STOP',... 
    'callback','set(gcbo,''userdata'',1,''string'',''DONE!'')', ... 
    'userdata',0) ; 

% Added initialization of "array" and array_32" arrays 
% array_32: stores the rectangle pos as uint32 
% array: stores the rectangle pos as double (added to make the script 
% running without an image on the axes) 
array=[]; 
array_32=[]; 
% 
while(1) 
    if get(ButtonHandle,'userdata') 
     break ; 
    end 

    % Commented type cast (default axix limit are [0 1] therefore 
    % pos=[ 0 1 0 0] 
    h = imrect; 
    % pos = uint32(wait(h)); 
    pos = wait(h); 

    % added message display and "pause" statement to allow pressing "Stop" 
    % button before drawing next rectangle 
    disp('Press STOP within 3 sec. to stop') 
    pause(3) 

    if ~isempty(pos) 
     rectangle('Position', pos, 'LineWidth',1, 'EdgeColor','k') 
     % if needed the edge color of each rectangle can be different 
     %  rectangle('Position', pos, 'LineWidth',1,'EdgeColor',[rand(3,1)]) 
     % 
     % Commented "for loop" to store rectangle pos since it is not needed 
     %  for i=1:4 
     %  counter=counter+1 
     % "array" is built as (N x 4) matrix, each row contains the "pos" of 
     % a rectangle (remove ";" to store it as a (1 x N) array 
     array = [array ; pos] 
     array_32 = [array_32 ; uint32(pos)] 
     %  end 

     delete(h) 

    end 

end 

溶液#2 主腳本

array=[]; 
axes 
ButtonHandle = uicontrol('style','push','String', 'Add rect',... 
    'callback','tmp=add_rect;array=[array;tmp]'); 

按鈕回調

function pos=add_rect() 
h = imrect; 
pos = wait(h); 
rectangle('Position', pos, 'LineWidth',1, 'EdgeColor','k') 
delete(h) 

希望這會有所幫助。

+0

謝謝。我今天剛看到你的解決方案。我也實現了暫停功能。非常感謝您發佈您的答案和所有的努力 –

+0

不客氣!這是一個非常有趣的問題,讓我學習新東西。 –