基本上,我有一个填充有0和1的矩阵,它代表图像。我本质上想要一个GUI,该GUI允许我在图像上随意绘制或绘制线条,因此本质上是Microsoft绘制在图像上绘制的功能。
感谢您的所有帮助。
答案 0 :(得分:1)
正如我评论的那样,您可以使用ginput
。
这是一个可以测试的简短程序。
fh = figure;
imageh = imshow(false(50));
% Create a button in the figure.
uicontrol('Parent',fh,'Style','pushbutton','String','paint','Callback',{@paintButtonCallback, imageh});
% button callback function
function paintButtonCallback(~,~,imageh)
[x,y] = ginput(1);
% round the values so they can be used for indexing.
x = round(x);
y = round(y);
% make sure the values do not go outside the image.
s = size(imageh.CData);
if x > s(2) || y > s(1) || x < 1 || y < 1
return
end
% make the selected pixel white.
imageh.CData(round(y),round(x)) = true;
end
我不确定是否有任何现有的工具箱可以让您像使用MS Paint一样方便地编辑图像。但是,可以自己编写代码。
要绘制一条线,可以使用'ginput(2)'取得两个点并绘制该线。请注意,findLine
功能并不完美。
[x,y] = ginput(2);
% find all pixels on the line xy
ind = findLine(size(imageh.CData),x,y);
% make the selected pixel white.
imageh.CData(ind) = true;
function [x,y] = findLine(x,y)
% Find all pixels that lie between points defined by [x(1),y(1)] and [x(2),y(2)].
supersampling = 1.2;
[x,y,~] = improfile(s,round(x),round(y),max([diff(x);diff(y)])*supersampling);
ind = sub2ind(s,round(x),round(y));
end
如果有图像处理工具箱,则可以选择使用drawline
,这样可以提供更好的绘制体验,并且可以使用createMask
函数获得行上的像素:
h = drawline;
ind = h.createMask;
drawfreehand
也可能相关:
h = drawfreehand;
x = h.Position(:,1);
y = h.Position(:,2);
如果不需要,可以使用delete(h)
删除在图像上创建的对象。在MATLAB documentation中查看更多类似的功能。
每次绘制点时都必须单击“绘制”按钮也很麻烦。要解决此问题,可以使用图中的ButtonDownFcn
。绘制按钮将根据情况使用有意义的回调或空值来更新ButtonDownFcn
:
function paintButtonCallback(obj,~,imageh)
if isempty(obj.Tag)
imageh.ButtonDownFcn = @paintMode;
obj.Tag = 'on';
else
imageh.ButtonDownFcn = '';
obj.Tag = '';
end
还有有意义的回调paintMode
:
function paintMode(~,~)
[x,y] = ginput(1);
% round the values so they can be used for indexing.
x = round(x);
y = round(y);
% make sure the values do not go outside the image.
s = size(imageh.CData);
if x > s(2) || y > s(1) || x < 1 || y < 1
return
end
% make the selected pixel white.
imageh.CData(y,x) = true;
end
完整的演示代码:
fh = figure;
imageh = imshow(false(20));
% Create buttons in the figure.
uicontrol('Parent',fh,'Style','pushbutton','String','paint','Callback',{@paintButtonCallback, imageh});
bh = uicontrol('Parent',fh,'Style','pushbutton','String','line','Callback',{@lineButtonCallback, imageh});
bh.Position(2) = 50;
bh2 = uicontrol('Parent',fh,'Style','pushbutton','String','line2','Callback',{@line2ButtonCallback, imageh});
bh2.Position(2) = 80;
bh3 = uicontrol('Parent',fh,'Style','pushbutton','String','free','Callback',{@freeButtonCallback, imageh});
bh3.Position(2) = 110;
% button callback function
function paintButtonCallback(obj,~,imageh)
if isempty(obj.Tag)
imageh.ButtonDownFcn = @paintMode;
obj.Tag = 'on';
else
imageh.ButtonDownFcn = '';
obj.Tag = '';
end
function paintMode(~,~)
[x,y] = ginput(1);
% round the values so they can be used for indexing.
x = round(x);
y = round(y);
% make sure the values do not go outside the image.
s = size(imageh.CData);
if x > s(2) || y > s(1) || x < 1 || y < 1
return
end
% make the selected pixel white.
imageh.CData(y,x) = true;
end
end
% button callback function
function lineButtonCallback(~,~,imageh)
% take two points at a time
[x,y] = ginput(2);
% make sure the values do not go outside the image.
s = size(imageh.CData);
if any(x > s(2)+0.5 | y > s(1)+0.5 | x < 0.5 | y < 0.5) || (diff(x) == 0 && diff(y) == 0)
return
end
% find all pixels on the line xy
ind = findLine(size(imageh.CData),x,y);
% make the selected pixel white.
imageh.CData(ind) = true;
end
function ind = findLine(s,x,y)
% Find all pixels that lie between points defined by [x(1),y(1)] and [x(2),y(2)].
supersampling = 1.2;
[x,y,~] = improfile(s,round(x),round(y),max([diff(x);diff(y)])*supersampling);
ind = sub2ind(s,round(x),round(y));
end
% button callback function
function line2ButtonCallback(~,~,imageh)
% take two points at a time
h = drawline;
ind = h.createMask;
delete(h);
% make the selected pixel white.
imageh.CData(ind) = true;
end
% button callback function
function freeButtonCallback(~,~,imageh)
% take two points at a time
h = drawfreehand;
x = h.Position(:,1);
y = h.Position(:,2);
delete(h);
ind = sub2ind(size(imageh.CData),round(y),round(x));
% make the selected pixel white.
imageh.CData(ind) = true;
end