2015-09-07 44 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

不客气!这是一个非常有趣的问题,让我学习新东西。 –