在图像上绘画MATLAB

时间:2019-04-20 18:16:07

标签: image matlab image-processing

基本上,我有一个填充有0和1的矩阵,它代表图像。我本质上想要一个GUI,该GUI允许我在图像上随意绘制或绘制线条,因此本质上是Microsoft绘制在图像上绘制的功能。

感谢您的所有帮助。

1 个答案:

答案 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