我创建了一个显示图像的GUI,用户必须能够执行以下操作:
1 - 使用鼠标选择几个点;
2 - 用户完成后,点击“返回”*;
3 - 在点击“返回”后,如果用户想要编辑其中一个点,他/她必须点击所需的点并将其拖动到他/她想要的位置。
我创建了这个函数:
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 - 它可以绘制图像,但坐标系在图的左上边缘处为零。 如何将其移动到图像的左上角?
Q2 - 如何实施第3项(如果用户想要编辑其中一个点,他/她必须点击所需的点并将其拖到他/她想要的位置)?
提前谢谢大家,
答案 0 :(得分:2)
您需要获取轴对象的CurrentPoint
,而不是获取图的CurrentPoint
。
cp = get(gca, 'CurrentPoint');
% Then get just the x/y position
cp = cp(1,1:2);
关于拖动点的问题的第二部分。您可能希望执行以下操作。
设置绘图对象的ButtonDownFcn
以触发回调功能
在此函数中,找到最接近点击点的图上的点。
跟踪此索引并设置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