#image #matlab #image-processing
#изображение #matlab #обработка изображений
Вопрос:
По сути, у меня есть матрица, заполненная 0 и 1, которая является представлением изображения. По сути, мне нужен графический интерфейс, который позволяет мне произвольно рисовать или создавать линии на изображении, поэтому, по сути, возможности Microsoft Paint для рисования на изображении.
Спасибо за всю вашу помощь.
Комментарии:
1. Вы пробовали ginput ?
Ответ №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.
Это также болезненно, когда вам приходится нажимать кнопку рисования каждый раз, когда вам нужно нарисовать точку. Чтобы преодолеть эту проблему, вы можете использовать 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 amp;amp; 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
Комментарии:
1. Так что это не совсем то, что я ищу, но это шаг в правильном направлении. Мне было просто интересно, есть ли что-нибудь в MATLAB или надстройке, которая, по сути, позволяет мне рисовать изображения Microsoft, поскольку я, вероятно, буду добавлять много строк к большому количеству изображений, а редактирование пикселей по одному не идеально (хотя ваше решение лучше, чем отслеживаниеотдельных пикселей и делать это вручную.
2. @jshackle Я также предлагаю вам обновить свой вопрос, поскольку вы не упомянули о необходимости добавления строк в изображение.