我正在尝试创建一个GUI控制程序,用于处理从显微镜摄像头获取的实时流,它应该识别流中用户定义对象的形状,计算它们的边缘和中心和叠加那些到流上,实际上跟踪对象。这已经很好了,我想继续,但我有一个问题,我只是无法中断正在进行帧处理的while循环。我希望能够做到这一点,因为可能有充分的理由在很久之后中止跟踪过程。我们的想法是只需要一个按钮,将循环的每次迭代检查的标志更改为false并完成它,只是它不起作用。
在网上搜索我发现它似乎是一个与回调队列相关的问题。只要循环正在运行,就不会注册用于改变break-flag的按钮,我通过在其回调中插入一个断点来测试,即使单击该按钮也不会触发该断点。有几次解决方案建议使用drawnow
暂时停止循环并处理任何排队的回调,但这似乎没有做任何事情。我还检查了按钮的Interruptible
和BusyAction
属性以及图片(需要点击以开始跟踪)是否分别设置为On
和queue
。它们是,但事实仍然是我不能打断那个循环。
如上所述,当点击轴对象中的livestream
时,跟踪开始。代码如下:
function ImageClickCallback(hObject, eventData, handles)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%--------- Selection of object to monitor --------%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% get handle to the axes object the stream is displayed in
axesHandle = get(hObject,'Parent');
% get coordinates of mouseclick and store them in a struct
coordinates = get(axesHandle,'CurrentPoint');
coordinates = coordinates(1,1:2);
% save those coordinates in the figure's appdata for further usage
setappdata(handles.figure1,'ccoordx',coordinates(1));
setappdata(handles.figure1,'ccoordy',coordinates(2));
% overlay marker onto video stream
hold on
scatter(coordinates(1),coordinates(2),400,'r','x', 'LineWidth', 2 );
hold off
% Display x and y values in textboxes
set(handles.text2, 'String', getappdata(handles.figure1, 'ccoordx'));
set(handles.text3, 'String', getappdata(handles.figure1, 'ccoordy'));
% enable tracking state
setappdata(handles.figure1, 'tracker', 1);
drawnow
set(findobj(gca,'BusyAction', 'cancel'), 'Interruptible', 'On');
tracker=getappdata(handles.figure1, 'tracker');
stream=getappdata(handles.figure1, 'stream');
while tracker == 1
% get currently displayed frame and convert to grayscale
singleframe=getsnapshot(stream);
% run the ObjectFinder and save the result, objectfinder is a self-programmed function thats doing the object-recognition
[alphamask, center, errorcode] = objectFinder(singleframe, getappdata(handles.figure1, 'ccoordx'), getappdata(handles.figure1,'ccoordy'), handles);
% abort if user clicked a non-object area
if errorcode == 2
msgbox('Not a valid object.');
return
end
% add alphamask to green picture to create overlay on axes1
hold on
set(findobj(gca,'BusyAction', 'cancel'), 'AlphaData', alphamask);
hold off
% update x and y coordinates of chosen object to its current
% center of mass
setappdata(handles.figure1,'ccoordx',center(1,1));
setappdata(handles.figure1,'ccoordy',center(1,2));
% make center of mass visible
set(findobj(gca,'Type','scatter'), 'XData', center(1,1));
set(findobj(gca,'Type','scatter'), 'YData', center(1,2));
flushdata(stream);
set(findobj(gca,'BusyAction', 'cancel'), 'Interruptible', 'On');
% this is where the condition is checked
tracker=getappdata(handles.figure1, 'tracker');
drawnow
end
% this part is supposed to delete the overlay when the loop is terminated
% by the button push
hold on
delete(findobj(gca,'Type', 'Scatter'));
set(findobj(gca,'BusyAction', 'cancel'), 'AlphaData', 0);
hold off
drawnow
setappdata
和getappdata
函数用于为整个程序提供几个数据,它们是有原因的。 videoObject
的声明,GUI的初始化等都发生在trackerGUI_OpeningFcn
中,如果被问到,我当然可以发布。
我试图用于循环终止的按钮的代码如下
function pushbutton1_Callback(hObject, eventdata, handles)
% disable tracking state
setappdata(handles.figure1, 'tracker', 0);
guidata(hObject, handles);
drawnow
正如我所说,跟踪工作正常(虽然只有大约2帧/秒,可能会高一点),我只是不能打断它。有趣的是,其他东西也没有用,可能是出于同样的原因:我的GUI中有一个滑块,用于设置模式识别功能中使用的fudgefactor
。如果我在跟踪处于活动状态时更改它,则可以立即在流/叠加中看到更改的fudgefactor
效果,但是应该显示当前所选因子的文本字段不会更新循环正在运行。如果不是,它会立即更新。
答案 0 :(得分:-1)
我第一次没有完全读完这个问题。此外,我试图评论,但我没有声誉。
为什么不尝试使用
初始化句柄中的跟踪器handles.tracker = 1;
在你的gui加载代码中,然后使用
循环while handles.tracker
在停止跟踪的按钮中,让您的回调执行handles.tracker = 0;