Краска на изображении MATLAB - PullRequest
0 голосов
/ 20 апреля 2019

По сути, у меня есть матрица, заполненная нулями и единицами, которая является представлением изображения. По сути, я хочу графический интерфейс, который позволяет мне произвольно рисовать или делать линии на изображении, поэтому, по сути, Microsoft рисует возможности рисования на изображении.

Спасибо за вашу помощь.

1 Ответ

1 голос
/ 20 апреля 2019

Как я уже прокомментировал, вы можете использовать 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

Если у вас есть Image Processing Toolbox, у вас есть возможность использовать drawline, что дает лучший опыт рисования, и вы можете получить пиксели на линии, используя createMask функцию:

h = drawline;
ind = h.createMask;

drawfreehand может также иметь отношение:

h = drawfreehand;
x = h.Position(:,1);
y = h.Position(:,2);

Вы можете удалить объект, созданный на изображении, с помощью delete(h), если он вам не нужен. См. Больше похожих функций в документации MATLAB .

Также болезненно, когда вам приходится нажимать кнопку рисования каждый раз, когда вам нужно нарисовать точку. Чтобы преодолеть эту проблему, вы можете использовать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...