在MATLAB中自定义获取像素坐标函数
我需要创建一个显示图像的GUI,用户必须能够执行以下操作: 1-使用鼠标选择多个点 2-用户完成后,点击“返回”* 3-点击“返回”后,如果用户想要编辑其中一个点,他/她必须单击所需点并将其拖动到他/她想要的位置 我创建了这个函数:在MATLAB中自定义获取像素坐标函数,matlab,matlab-figure,matlab-guide,Matlab,Matlab Figure,Matlab Guide,我需要创建一个显示图像的GUI,用户必须能够执行以下操作: 1-使用鼠标选择多个点 2-用户完成后,点击“返回”* 3-点击“返回”后,如果用户想要编辑其中一个点,他/她必须单击所需点并将其拖动到他/她想要的位置 我创建了这个函数: function [x, y] = test(img) [lin, col] = size(img); fig = figure('WindowButtonDownFcn', {@func, lin, col}, 'KeyPressFcn', @keyfunc);
function [x, y] = test(img)
[lin, col] = size(img);
fig = figure('WindowButtonDownFcn', {@func, lin, col}, 'KeyPressFcn', @keyfunc);
imshow(img, []);
% axs = axes('position', [1 col 1 lin]);
set(gca, 'Ydir', 'reverse');
x = [];
y = [];
uiwait(fig);
function func(src, callback, lin, col)
seltype = get(fig, 'SelectionType');
set(gca, 'Ydir', 'reverse');
if strcmp(seltype, 'normal')
set(fig, 'Pointer', 'circle');
cp = get(fig, 'CurrentPoint');
xinit = cp(1, 1);
yinit = cp(1, 2);
x = [x, xinit];
y = [y, yinit];
hl = line('XData', xinit, 'YData', yinit, 'color', 'b', 'Marker', '.');
set(fig, 'WindowButtonMotionFcn', {@moveMouse, lin, col});
set(fig, 'WindowButtonUpFcn', @mouseRelease);
end
function moveMouse(src, callback, lin, col)
cp = get(fig, 'CurrentPoint');
xdata = [xinit, cp(1, 1)];
ydata = [yinit, cp(1, 2)];
set(hl, 'XData', xdata);
set(hl, 'YData', ydata);
drawnow;
end
function mouseRelease(src, callback)
last_selection = get(fig, 'SelectionType');
if strcmp(last_selection, 'alt')
set(fig, 'Pointer', 'arrow');
set(fig, 'WindowButtonMotionFcn','');
set(fig, 'WindowButtonUpFcn','');
else
return;
end
end
end
function keyfunc(src, callback)
keypressed = get(fig, 'CurrentCharacter');
if keypressed == 13
uiresume(fig);
end
end
end
Q1-它可以绘制图像,但坐标系的零位于图形的左上角。如何将其移动到图像的左上角
问题2-如何实现项目编号3(如果用户想要编辑其中一个点,他/她必须单击所需点并将其拖动到他/她想要的位置)
提前感谢大家,您不需要获取图形的
CurrentPoint
,而是需要获取axes对象的CurrentPoint
有关拖动点的问题的第二部分。您可能需要执行以下操作
按钮downfcn
,以触发回调函数WindowButtonMotionFcn
,以便无论何时移动鼠标,该点都会移动到该位置WindowButtonUpFcn
,以便在释放鼠标按钮时重置WindowButtonMotionFcn
set(hl, 'ButtonDownFcn', @(src,evnt)clickedLine(src))
function clickedLine(src, evnt)
cp = get(ancestor(src, 'axes'), 'CurrentPoint');
xdata = get(src, 'XData');
ydata = get(src, 'YData');
% Find the index of the closest point
[~, ind] = min((xdata - cp(1,1)).^2 + (ydata - cp(1,2)).^2);
hfig = ancestor(src, 'figure');
switch get(hfig, 'SelectionType')
case 'alt'
% Right click deletes a point
xdata(ind) = [];
ydata(ind) = [];
set(src, 'XData', xdata, 'YData', ydata);
otherwise
% Set the WindowMotionFcn callback to track this point
set(hfig, 'WindowButtonMotionFcn', @(s,e)dragPoint(src,ind), ...
'WindowButtonUpFcn', @(s,e)stopDrag(s));
end
end
function dragPoint(plt, index)
xdata = get(plt, 'xdata');
ydata = get(plt, 'ydata');
% Get the current point
cp = get(ancestor(plt, 'axes'), 'CurrentPoint');
xdata(index) = cp(1,1);
ydata(index) = cp(1,2);
% Update the data and refresh
set(plt, 'XData', xdata, 'YData', ydata);
drawnow
end
function stopDrag(hfig)
set(hfig, 'WindowButtonMotionFcn', '', ...
'WindowButtonUpFcn', '');
end
您不需要获取图形的
CurrentPoint
,而需要获取axes对象的CurrentPoint
有关拖动点的问题的第二部分。您可能需要执行以下操作
按钮downfcn
,以触发回调函数WindowButtonMotionFcn
,以便无论何时移动鼠标,该点都会移动到该位置WindowButtonUpFcn
,以便在释放鼠标按钮时重置WindowButtonMotionFcn
set(hl, 'ButtonDownFcn', @(src,evnt)clickedLine(src))
function clickedLine(src, evnt)
cp = get(ancestor(src, 'axes'), 'CurrentPoint');
xdata = get(src, 'XData');
ydata = get(src, 'YData');
% Find the index of the closest point
[~, ind] = min((xdata - cp(1,1)).^2 + (ydata - cp(1,2)).^2);
hfig = ancestor(src, 'figure');
switch get(hfig, 'SelectionType')
case 'alt'
% Right click deletes a point
xdata(ind) = [];
ydata(ind) = [];
set(src, 'XData', xdata, 'YData', ydata);
otherwise
% Set the WindowMotionFcn callback to track this point
set(hfig, 'WindowButtonMotionFcn', @(s,e)dragPoint(src,ind), ...
'WindowButtonUpFcn', @(s,e)stopDrag(s));
end
end
function dragPoint(plt, index)
xdata = get(plt, 'xdata');
ydata = get(plt, 'ydata');
% Get the current point
cp = get(ancestor(plt, 'axes'), 'CurrentPoint');
xdata(index) = cp(1,1);
ydata(index) = cp(1,2);
% Update the data and refresh
set(plt, 'XData', xdata, 'YData', ydata);
drawnow
end
function stopDrag(hfig)
set(hfig, 'WindowButtonMotionFcn', '', ...
'WindowButtonUpFcn', '');
end
谢谢你的回答。还有一个问题:我可以添加“删除”功能吗?我添加了它,但它只影响结果(x,y向量),但不更新行。@Gabs Yes您可以使用
clickedLine中的ind
删除特定元素。然后你会想更新绘图xdata
和ydata
。对不起,我到底是怎么做到的?@Gabs如果你不知道怎么做,我猜你没有写这段代码。。。我已经对代码进行了更新,所以右键单击绘图可以删除一个点。我确实编写了代码,但编写GUI绝对不是我的领域。。。我真的不明白回调是如何工作的。。。对不起…:-(谢谢你的回答。再问一个问题:我可以添加“删除”功能吗?我添加了它,但它只影响结果(x,y向量)但是它不会更新线条。@Gabs是的,你可以使用点击线条中的ind
删除特定元素。然后你会想更新绘图xdata
和ydata
。对不起,但我到底是怎么做的?@Gabs如果你不知道怎么做,我猜你没有写这段代码……我做了一个简单的解释n更新代码,以便右键单击绘图可以删除一个点我确实编写了代码,但编写GUI绝对不是我的领域…我真的不明白回调是如何工作的…抱歉…:-(