多个可拖动矩形matlab:额外矩形
我正在编写一个代码来获取用户输入的多个可拖动矩形的位置。代码运行完全正常。但是,按下按钮后,代码不会向前移动,直到您再绘制一个矩形。我认为问题是多个可拖动矩形matlab:额外矩形,matlab,Matlab,我正在编写一个代码来获取用户输入的多个可拖动矩形的位置。代码运行完全正常。但是,按下按钮后,代码不会向前移动,直到您再绘制一个矩形。我认为问题是pos=uint32(等待(h))语句无限期地等待另一个位置,只有在绘制另一个矩形后才考虑按钮手柄。我确实需要wait(h)语句,因为getposition函数对我不起作用。我真的很感谢你能提供的任何帮助,以下是我代码的一部分 代码: im_des=rgb2gray('image_name.jpg'); ButtonHandle = uicontrol(
pos=uint32(等待(h))代码>语句无限期地等待另一个位置,只有在绘制另一个矩形后才考虑按钮手柄。我确实需要wait(h)
语句,因为getposition
函数对我不起作用。我真的很感谢你能提供的任何帮助,以下是我代码的一部分
代码:
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
我已经找到了在按下停止按钮后需要绘制一个额外矩形的原因,并且找到了一些可能的解决方案来解决这个问题
简言之,问题在于。。。MatLab比你快
换句话说,这是一步一步发生的:
假设您只想绘制一个矩形,然后按下“停止”按钮停止绘制
while
循环开始时的if
语句中的条件未经验证(您尚未按下按钮),因此循环将继续
if get(ButtonHandle,'userdata')
break ;
end
然后执行imrect
语句
h = imrect;
它启动矩形绘制过程:您可以绘制矩形、移动矩形、调整矩形大小等等
一旦开始绘制,就会执行下一条语句
pos = uint32(wait(h));
if get(ButtonHandle,'userdata')
h = imrect;
pos = uint32(wait(h));
wait
函数将阻止MatLab命令行,直到您在矩形上双击退出绘图模式
如果您已经绘制了一个有效的矩形,那么下一条语句将绘制实际的矩形,将矩形的位置存储在“数组”中,并删除imrect
对象的handle
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
循环的新迭代将开始
再次执行第一条语句
pos = uint32(wait(h));
if get(ButtonHandle,'userdata')
h = imrect;
pos = uint32(wait(h));
如果在新的迭代开始之前,您没有那么快(并且您不可能)到达“停止”按钮并按下它,则不会验证if
条件,因此
执行imrect
序列
pos = uint32(wait(h));
if get(ButtonHandle,'userdata')
h = imrect;
pos = uint32(wait(h));
因为你的意图是画另一个矩形
这是在按下“停止”按钮后实际停止脚本所需的“附加”矩形
当MatLab命令行被wait
函数阻塞时,callback
listner不被阻塞,因此您可以按下pussh按钮,并且userdata
的值设置为1
然而,绘图过程已经启动
因此,您需要绘制“附加”矩形,双击退出wait
,以便启动“while”循环的另一次迭代
此时,if
条件最终得到验证,break
语句停止while
循环的执行
事情就是这样
我发现了两种可能的解决方案:第一种方案允许保持脚本“几乎”不变,第二种方案意味着改变GUI
的概念
第一个解决方案允许您。。。比MatLab更快
如果在调用wait
(例如pause(3)
)后插入pause
语句,则在新迭代开始之前,您将有3秒钟的时间到达并按下“Stop”
这允许将checallback
settinguserdata
设置为1,并在验证循环时在开始处设置if
条件,从而停止脚本的执行,而无需绘制任何额外的矩形
第二种解决方案包括更改GUI
的行为:
您可以删除while
循环并更改按钮回调
,以便它负责调用imrect
并绘制矩形(实际上,您必须移动
按钮cllback
中循环时内的代码
这样,GUI的行为将是:任何时候您想要添加一个矩形,您必须按下按钮
在这里,您可以找到这两种解决方案的脚本
请注意,为了使其运行,我对您的附加代码进行了一些附加修改:
我已删除uint32强制转换
:轴中没有图片,默认轴
限制为[0 1],
如果将pos
转换为无符号32位整数
,pos将为[0 1 0]
我还删除了for
循环,将pos
存储在数组中:实际上不需要它
解决方案#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)
希望这能有所帮助。谢谢。我今天刚刚看到了您的解决方案。我也实现了暂停功能。非常感谢您发布了答案并尽了最大努力。不客气!这是一个非常有趣的问题,让我学到了一些新东西。