Image 基于MATLAB的图像绘制

Image 基于MATLAB的图像绘制,image,matlab,image-processing,Image,Matlab,Image Processing,基本上,我有一个用0和1填充的矩阵,这是图像的表示。我本质上想要一个GUI,它允许我在图像上任意绘制或划线,因此本质上,Microsoft paint具有在图像上绘制的功能 谢谢您的帮助。正如我所评论的,您可以使用 这是一个可以测试的简短程序 fh = figure; imageh = imshow(false(50)); % Create a button in the figure. uicontrol('Parent',fh,'Style','pushbutton','String','

基本上,我有一个用0和1填充的矩阵,这是图像的表示。我本质上想要一个GUI,它允许我在图像上任意绘制或划线,因此本质上,Microsoft paint具有在图像上绘制的功能


谢谢您的帮助。

正如我所评论的,您可以使用

这是一个可以测试的简短程序

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
如果您有图像处理工具箱,您可以选择使用drawline,这将提供更好的绘制体验,并且您可以使用createMask函数获得线条上的像素:

h = drawline;
ind = h.createMask;
drawfreehand也可能与以下内容相关:

h = drawfreehand;
x = h.Position(:,1);
y = h.Position(:,2);
如果不需要,可以使用deleteh删除在图像上创建的对象。请参阅中的更多类似函数

每次需要绘制点时,都必须单击“绘制”按钮,这也是一种痛苦。要解决此问题,可以使用图形的ButtonDownFcn。绘制按钮将根据情况使用有意义的回调或空值更新ButtonDownFcn:

function paintButtonCallback(obj,~,imageh)
if isempty(obj.Tag)
    imageh.ButtonDownFcn = @paintMode;
    obj.Tag = 'on';
else
    imageh.ButtonDownFcn = '';
    obj.Tag = '';
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

你试过了吗?这不是我想要的,但这是朝着正确方向迈出的一步。我基本上只是想知道MATLAB或附加组件中是否有任何东西可以让我在microsoft中绘制图像,因为我可能会在很多图像中添加很多线条,并逐个编辑像素。虽然您的解决方案比跟踪单个像素并手动执行要好,但这并不理想。@jshackle I还建议您更新您的问题,因为您没有提到需要在图像中添加行。
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