顕微鏡のカメラから取得したライブストリームを処理するためのGUI制御プログラムを作成しようとしていますが、ストリーム内のユーザー定義オブジェクトの形状を認識しているはずですそれらのエッジと中心を計算し、それらをストリーム上にオーバーレイし、実際にオブジェクトを追跡する。これはすでにうまくいきましたが、私は続行したいと思いますが、フレーム処理を行っているwhileループを中断できないという問題があります。私はそれを行うことができるようにしたいと思います。なぜなら、ずっと後で追跡プロセスを中止するのが良い理由があるからです。そのアイデアは、ループの各反復でチェックされたフラグをfalseに変更して終了するプッシュボタンを持つだけで、機能しないということだけでした。ボタンでwhileループを停止できません
ネットを検索すると、コールバックキュー関連の問題のようです。ブレークフラグを変更するために使用されるボタンのプッシュは、ループが実行されている間は登録されません。コールバックにブレークポイントを挿入することでテストしましたが、ボタンをクリックしてもトリガーされません。いくつかのケースでは、ループを一時的に停止し、キューに入れられたコールバックを処理するためにdrawnow
を使用するように提案されていましたが、何もしないようです。また、ボタンと画像(トラッキングを開始するためにクリックする必要がある)のInterruptible
とBusyAction
のプロパティがそれぞれOn
とqueue
に設定されているかどうかを確認しました。それらはありますが、実際には私はそのループを中断できません。
上記のように、軸オブジェクト内のlivestream
がクリックされると、トラッキングが開始されます。そのためのコードは次のとおりです。setappdata
とgetappdata
の機能は、プログラム全体で利用可能なデータのいくつかの作品を作るために使用されている、彼らは理由がある
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
。 videoObject
の宣言、GUIの初期化などは、trackerGUI_OpeningFcn
で行われます。もちろん、これはもちろん質問すると投稿することもできます。
function pushbutton1_Callback(hObject, eventdata, handles)
% disable tracking state
setappdata(handles.figure1, 'tracker', 0);
guidata(hObject, handles);
drawnow
を次のように私は、トラッキングがこれはできる、唯一の約2コマ/秒ではある(正常に動作し、言ったように
私は、ループ終了のために使用しようとしているボタンのコードですちょっと高いです)、私はそれを中断することはできません。面白いことに、おそらく同様の理由でおそらく他の何かがうまくいきません。私はfudgefactor
をパターン認識機能で使用するように設定した私のGUIのスライダーを持っています。トラッキングがアクティブな間に変更すると、変更されたfudgefactor
のエフェクトはすぐにストリーム/オーバーレイに表示されますが、ループが実行されている間は現在選択されているファクタを示すはずのテキストフィールドは更新されません。そうでない場合は、すぐに更新されます。
トグルボタンを使用して、whileループでトグルの状態をチェックして、ループから脱出するかどうかを判断してください。 – excaza
1. 'drawnow'を' pause(0.001) 'に置き換えてみてください。 2。whileループを削除し、ボタンが押されたときに 'pushbutton1_Callback'が実行されていることを確認します。 3. MatlabおよびOSのどのバージョンを使用していますか? – Rotem
マルチスレッドコードを使用して複数のジョブを並行して実行することができます(ループが実行されているときにGUIの他の部分が動作している場合)。グローバル変数を作成してwhileループのフラグとして使用し、GUI用の別のスレッドを作成し、ボタンを使用してフラグを設定してください。 –