Подвыборка или упрощает ROI от руки

Этот пример показывает, как подвыбрать или уменьшать число точек в объекте Freehand ROI.

Введение

Функция drawfreehand создает сглаженно выглядящую видимую область (ROI) от руки. Однако ребро на самом деле сделано из дискретных точек, распределенных все время по контуру. Два фактора способствуют тому, как сглаженный ROI от руки смотрит: 1) плотность точек и 2) свойство Smoothing объекта ROI от руки.

При рисовании в интерактивном режиме, движение мыши определяет плотность точек. Для крупных комплексных КОРОЛЕЙ используемое число точек может быть довольно большим.

Свойство Smoothing управляет, как контур смотрит. По умолчанию объект от руки использует Гауссово ядро сглаживания со значением сигмы 1 и размером фильтра 5. Изменение этого значения только изменяется, как контур смотрит, это не изменяет базовое свойство Position объекта.

Плотность по умолчанию точек

Сокращение плотности точек может помочь уменьшать пробел, требуемый хранить данные о ROI, и может также ускорить любое вычисление, которое зависит от количества этих точек. Один способ уменьшать плотность точек состоит в том, чтобы подвыбрать точки, например, выберите любую точку.

Создайте демонстрационный ROI от руки путем преобразования маски в ROI. ROI является очень плотным, поскольку каждый граничный пиксель будет соответствовать точке в ROI.

im = imread('football.jpg');
bw = im(:,:,1)>200;
bw = bwareafilt(bw, 1);
bloc = bwboundaries(bw,'noholes');
roipos = fliplr(bloc{1});
imshow(im);
hfh = drawfreehand('Position', roipos);

Чтобы визуализировать плотность, поверните каждое местоположение в ROI в Waypoint.

hfh.Waypoints(:) = true;

title('Original density');
snapnow

% Zoom in
xlim([80 200]);
ylim([70 160]);
snapnow

Подвыборка точки положения

Подвыберите точки, которые составляют свойство Position ROI от руки. Поскольку ROI от руки является очень плотным. Подвыборка может существенно уменьшать размер, не освобождая точность. Запросите начальное полное/мелкомодульное положение.

fpos = hfh.Position;

Подвыборка, выбирая каждое 4-е положение только.

cpos = fpos(1:2:end,:);

Обновите ROI.

hfh.Position = cpos;

Превратите все точки в Waypoints.

hfh.Waypoints(:) = true;
title('Simple Subsample (factor of 4)');
snapnow

Подвыборка - Используя скорость изменения

Лучший подход, чтобы подвыбрать точки должен был бы выборочно начать удалять точки, которые имеют низкое искривление. Имеет больше смысла удалять точку, которая приезжает относительно прямой фрагмент ROI, а не одной близости кривая. Один простой подход, чтобы задать значение искривления должен измерить уровень изменения в местоположениях положения.

Измерьте скорость изменения. Сосед первой точки является последней точкой.

dfpos = diff([fpos(end,:); fpos]);

Задайте оперативную меру искривления на основе простого фильтра нижних частот.

cm = sum(abs(conv2(dfpos, ones(3,2),'same')),2);

Сортировка искривлением.

[~, cmInds] = sort(cm);

Выберите 3/4 точек с более низкими значениями искривления, чтобы удалить из ROI.

numPointsToCull = round(0.25*size(fpos,1));

Удалите те положения.

cpos = fpos;
cpos(cmInds(1:numPointsToCull),:) = [];

Обновите ROI, включив весь Waypoints, чтобы видеть влияние.

hfh.Position = cpos;
hfh.Waypoints(:) = true;
title('Curvature Based Subsample (factor of 4)');
snapnow

Интерактивная подвыборка

Другой способ подвыбрать состоит в том, чтобы использовать события, чтобы сделать этот процесс легче. Сначала создайте прослушиватель, чтобы в интерактивном режиме изменить число точек, которое использует ROI от руки. Используйте свойство UserData объекта Freehand кэшировать полное разрешение данные Position, наряду с его значениями искривления. Затем добавьте пользовательское контекстное меню в объект ROI путем создания нового uimenu и порождения его к UIContextMenu объекта Freehand. Этот пункт меню позволит нам завершать ROI, который удаляет временный кэш.

% Restore original ROI, and cache the original position along with its
% curvature measure in UserData
hfh.Position = fpos;
hfh.Waypoints(:) = true;
hfh.UserData.fpos = fpos;
hfh.UserData.cmInds = cmInds;

Ответьте на прокрутку мыши

h = gcf;
h.WindowScrollWheelFcn = @(h, evt) changeSampleDensity(hfh, evt);

Добавьте, что контекстное меню, чтобы завершить ROI и выполнить любого моется необходимый

uimenu(hfh.UIContextMenu, 'Text','Finalize',...
    'MenuSelectedFcn', @(varargin)finalize(hfh));

title('Scroll to change density interactively');

Анимация интерактивной подвыборки

Функция обратного вызова - изменяет демонстрационную плотность на основе прокрутки мыши

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

function changeSampleDensity(hfh, evt)
currentNumPoints = size(hfh.Position,1);
% 5% of original for each scroll.
numChangePoints = round(size(hfh.UserData.fpos,1)*0.05);

newNumPoints = currentNumPoints + evt.VerticalScrollCount*numChangePoints;
newNumPoints = max(3, min(size(hfh.UserData.fpos,1), newNumPoints));

numPointsToCull = size(hfh.UserData.fpos,1) - newNumPoints;

% Pick the full resolution cached position
cpos = hfh.UserData.fpos;
cmInds = hfh.UserData.cmInds;
% cull that to get the coarse position
cpos(cmInds(1:numPointsToCull),:) = [];

% Update the ROI and show all the points used
hfh.Position = cpos;
hfh.Waypoints(:) = true;
end

Функция обратного вызова - завершает ROI от руки

Удалите и создайте новый ROI От руки с подвыбранными точками, чтобы экономить на пробеле.

function finalize(hfh)
h = ancestor(hfh, 'figure');
% Reset the mouse scroll wheel callback
h.WindowScrollWheelFcn = [];
% Save finalized set of points
pos = hfh.Position;
% Delete and create a new Freehand ROI
delete(hfh);
drawfreehand(gca, 'Position', pos);
end

Смотрите также

| | |

Похожие темы