2017-02-24 14 views
2

顕微鏡のカメラから取得したライブストリームを処理するためのGUI制御プログラムを作成しようとしていますが、ストリーム内のユーザー定義オブジェクトの形状を認識しているはずですそれらのエッジと中心を計算し、それらをストリーム上にオーバーレイし、実際にオブジェクトを追跡する。これはすでにうまくいきましたが、私は続行したいと思いますが、フレーム処理を行っているwhileループを中断できないという問題があります。私はそれを行うことができるようにしたいと思います。なぜなら、ずっと後で追跡プロセスを中止するのが良い理由があるからです。そのアイデアは、ループの各反復でチェックされたフラグをfalseに変更して終了するプッシュボタンを持つだけで、機能しないということだけでした。ボタンでwhileループを停止できません

ネットを検索すると、コールバックキュー関連の問題のようです。ブレークフラグを変更するために使用されるボタンのプッシュは、ループが実行されている間は登録されません。コールバックにブレークポイントを挿入することでテストしましたが、ボタンをクリックしてもトリガーされません。いくつかのケースでは、ループを一時的に停止し、キューに入れられたコールバックを処理するためにdrawnowを使用するように提案されていましたが、何もしないようです。また、ボタンと画像(トラッキングを開始するためにクリックする必要がある)のInterruptibleBusyActionのプロパティがそれぞれOnqueueに設定されているかどうかを確認しました。それらはありますが、実際には私はそのループを中断できません。

上記のように、軸オブジェクト内のlivestreamがクリックされると、トラッキングが開始されます。そのためのコードは次のとおりです。setappdatagetappdataの機能は、プログラム全体で利用可能なデータのいくつかの作品を作るために使用されている、彼らは理由がある

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のエフェクトはすぐにストリーム/オーバーレイに表示されますが、ループが実行されている間は現在選択されているファクタを示すはずのテキストフィールドは更新されません。そうでない場合は、すぐに更新されます。

+2

トグルボタンを使用して、whileループでトグルの状態をチェックして、ループから脱出するかどうかを判断してください。 – excaza

+0

1. 'drawnow'を' pause(0.001) 'に置き換えてみてください。 2。whileループを削除し、ボタンが押されたときに 'pushbutton1_Callback'が実行されていることを確認します。 3. MatlabおよびOSのどのバージョンを使用していますか? – Rotem

+0

マルチスレッドコードを使用して複数のジョブを並行して実行することができます(ループが実行されているときにGUIの他の部分が動作している場合)。グローバル変数を作成してwhileループのフラグとして使用し、GUI用の別のスレッドを作成し、ボタンを使用してフラグを設定してください。 –

答えて

-1

初めて完全に質問を読んでいませんでした。また、私はコメントしようとしましたが、私は評判がありません。

なぜあなたはあなたのGUIローディングコードで

handles.tracker = 1; 

とハンドルでトラッカーを初期化しようとし、その後、ループの追跡を停止するには、ボタンで

while handles.tracker 

を使用して、コールバックを持っていません実行handles.tracker = 0;

+0

私はそれをmondayで試してみますが、set/getappdata(handles.figure1 'tracker')で同じことをしている間にhandles.trackerが動作するはずの理由がありますか?私はそれが同じであると考えました、唯一のフラグがそれぞれハンドルと図に保存されています。何か不足していますか? – Smaakerchef

関連する問題