删除或移动后刷新所有绘制点的位置 - Matlab App designer

Refresh positions of all draw points after deleting or moving - Matlab App designer

我做了一个带有两个按钮和轴的应用程序设计器 GUI。第一个 (LoadimageButton) 正在加载 pappers 图像,我可以标记点,直到我按下退出键。第二个按钮打印出点坐标(PositionButton)。

我注意到按下这两个按钮后我可以在轴上移动点并更改它们的位置或删除它们。问题是,当我按下删除键(在上下文菜单中)时,我在按下 PositionButton:

后收到此错误
Error using images.roi.Point/get
Invalid or deleted object.

Error in tempDrwPnt1/PositionButtonPushed (line 61)
positions = cell2mat(get(app.pointhandles, 'position'))

Error while evaluating Button PrivateButtonPushedFcn.

删除点后如何刷新app.pointhandles?

代码:

function LoadimageButtonPushed(app, event)
            imshow('peppers.png','Parent',app.ImageAxes); 
          
            userStopped = false; 
            app.pointhandles = gobjects(); 
                   while ~userStopped
                        roi = drawpoint(app.ImageAxes); 
                        if ~isvalid(roi) || isempty(roi.Position)
                            % End the loop
                            userStopped = true;
                        else
                            % store point object handle
                            app.pointhandles(end+1) = roi;
                        end
                   end 
            

            addlistener(roi,'MovingROI',@allevents);
            addlistener(roi,'ROIMoved',@allevents);
  
            app.pointhandles(1) = []; 
            
            function allevents(src,evt)
                evname = evt.EventName;
                switch(evname)
                    case{'MovingROI'}
                        disp(['ROI moving previous position: ' mat2str(evt.PreviousPosition)]);
                        disp(['ROI moving current position: ' mat2str(evt.CurrentPosition)]);
                    case{'ROIMoved'}
                        disp(['ROI moved previous position: ' mat2str(evt.PreviousPosition)]);
                        disp(['ROI moved current position: ' mat2str(evt.CurrentPosition)]);
                end
            end 
end


% Button pushed function: PositionButton
function PositionButtonPushed(app, event) 
positions = cell2mat(get(app.pointhandles, 'position'))
end

您可以在 PositionButtonPushed 函数中添加检查每个 pointhandles 元素是否有效,如果有效则报告它,如果无效则将其删除

类似

function PositionButtonPushed(app, event)
    nPts = numel(app.pointhandles);
    positions = NaN(nPts,2); % array to hold positions
    for iPt = nPts:-1:1 % loop backwards so we can remove elements without issue
        if isvalid( app.pointhandles(iPt) )
            positions(iPt,:) = get(app.pointhandles(iPt),'position');
        else
            % No longer valid (been deleted), remove the reference
            app.pointhandles(iPt) = [];
            % Also remove from the positions output
            positions(iPt,:) = [];
        end
    end
end

我现在没有可用的兼容 MATLAB 版本来测试它,但我假设内置函数 isvalid 适用于 Point 对象,否则你将不得不添加你自己的有效性检查。或者,您可以 try 获得位置,并在 catch 内执行删除(由上面的 else 处理),但我通常建议不要 try/catch 如果您可以改为检查特定(已知)问题。

我经常使用类似的东西(例如轴),但将无效句柄的清理功能捆绑到它自己的函数中。在这种情况下,它会让您在获取剩余有效点的位置之前添加一个函数调用。

我还通过使用 arrayfun 使它更加简洁,但在引擎盖下它与上述循环的方法相同:

function PositionButtonPushed(app, event )
    app.checkHandleValidity(); % cleanup handles just in case

    positions = cell2mat(get(app.pointhandles, 'position'));
end

function checkHandleValidity( app )
   bValid = arrayfun( @isvalid, app.pointhandles ); % Check validity
   app.pointhandles( ~bValid ) = [];                % Remove invalid elements
end