Этот пример показов, как выделить или уменьшить число точек в Freehand
Объект информация только для чтения.
The drawfreehand
функция создает плавный вид, freehand, представляющий интерес регион (ROI). Однако ребро информация только для чтения на самом деле сделан из дискретных точек, распределенных по всему контуру. Два фактора способствуют тому, как сглаживает информацию только для чтения freehand: 1) плотность точек и 2) Smoothing
свойство объекта freehand информации только для чтения.
При интерактивном рисовании движение мыши определяет плотность точек. Для больших сложных ROIs используемые числа точек могут быть довольно большими.
The Smoothing
свойство управляет внешним видом контура. По умолчанию в Freehand
объект использует Гауссово сглаживающее ядро со значением сигмы 1 и размером фильтра 5. Изменение этого значения только изменяет вид контура, но не меняет базовую Position
свойство объекта.
Уменьшение плотности точек может помочь уменьшить пространство, необходимое для хранения данных информация только для чтения, а также может ускорить любые расчеты, которые зависят от количества этих точек. Один из способов уменьшить плотность точек - подметить точки, например, выбрать каждую другую точку.
Создайте выборку информации только для чтения freehand путем преобразования маски в информацию только для чтения. Информация только для чтения очень плотный, поскольку каждый краевой пиксель будет соответствовать точке в информация только для чтения.
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);
Чтобы визуализировать плотность точек, поверните каждую точку информация только для чтения в путевую точку.
hfh.Waypoints(:) = true; title('Original density'); snapnow % Zoom in. xlim([80 200]); ylim([70 160]); snapnow
Выделите точки, составляющие Position
свойство freehand ROI. Поскольку freehand ROI очень плотный. Субдискретизация может существенно уменьшить размер, не ослабляя точность. Запросите начальное, полное, мелкозернистое положение.
fpos = hfh.Position;
Подвыборка, выбор каждой другой точки.
cpos = fpos(1:2:end,:);
Обновите свойство Position ROI.
hfh.Position = cpos;
Чтобы увидеть плотность, превратите все точки в путевые точки.
hfh.Waypoints(:) = true;
title('Simple Subsample');
snapnow
Лучшим подходом к подопределению точек было бы выборочное начало удаления точек с низкой кривизной. Имеет больше смысла удалять точку, которая находится вдоль относительно прямого фрагмента информация только для чтения, а не рядом с кривой. Одним из простых методов определения значения кривизны является измерение скорости изменения положения.
Измерьте скорость изменения. Соседом первой точки является последняя точка.
dfpos = diff([fpos(end,:); fpos]);
Задайте специальную меру кривизны на основе простого lowpass.
cm = sum(abs(conv2(dfpos, ones(3,2),'same')),2);
Сортировка по кривизне.
[~, cmInds] = sort(cm);
Выберите 3/4 точек с более низкими значениями кривизны, чтобы удалить из информация только для чтения.
numPointsToCull = round(0.25*size(fpos,1));
Снимите эти положения.
cpos = fpos; cpos(cmInds(1:numPointsToCull),:) = [];
Обновите информация только для чтения, включив все Waypoints, чтобы увидеть влияние.
hfh.Position = cpos;
hfh.Waypoints(:) = true;
title('Curvature Based Subsample (factor of 4)');
snapnow
reduce
метод по объектам freehand информации только для чтенияЕще лучшим подходом к подопределению точек было бы использование reduce
метод для объекта информация только для чтения. The reduce
метод действует непосредственно на Position
свойство объекта информация только для чтения. Вы можете повлиять на число точек, задав значение допуска между [0 1.0] в качестве необязательного входного параметра. Допустимое значение по умолчанию равно 0,01.
Сбросьте Position
свойство и вызов reduce
на объекте информация только для чтения.
hfh.Position = fpos; reduce(hfh); % View the updated ROI, turning all the points into waypoints to see the % impact. hfh.Waypoints(:) = true; title('Subsampling using reduce method'); snapnow
Другой способ subsample - использовать события, чтобы упростить этот процесс. Сначала создайте прослушиватель, чтобы в интерактивном режиме изменить число точек, которую использует информация только для чтения freehand. Используйте UserData
свойство объекта Freehand для кэширования полного разрешения Position
данные наряду с текущим значением допуска. Затем добавьте пользовательское контекстное меню к объекту информация только для чтения путем создания нового
и воспитание его в uimenu
UIContextMenu
объекта Freehand. Эта опция меню позволяет вам завершить информация только для чтения, который удаляет временный кэш.
Восстановите исходный информация только для чтения и кэшируйте исходное положение вместе с измерением кривизны в UserData.
hfh.Waypoints(:) = true; hfh.UserData.fpos = fpos; hfh.UserData.tol = 0;
Ответьте на прокрутку мыши.
h = gcf; h.WindowScrollWheelFcn = @(h, evt) changeSampleDensity(hfh, evt);
Добавьте контекстное меню, чтобы завершить информация только для чтения и выполнить необходимую очистку.
uimenu(hfh.UIContextMenu, 'Text','Finalize',... 'MenuSelectedFcn', @(varargin)finalize(hfh)); title('Scroll to change density interactively');
Эта функция вызывается при действии прокрутки. Прокрутка вверх увеличивает плотность, а прокрутка вниз уменьшает ее. Это позволяет вам в интерактивном режиме выбрать число точек, которые нужно сохранить.
function changeSampleDensity(hfh, evt) % Restore Position property of ROI. hfh.Position = hfh.UserData.fpos; % Change tolerance by a fixed amount based on the direction of the scroll. % This code changes the tolerance by 0.01 for every scroll increment. tol = hfh.UserData.tol + 0.01 * (evt.VerticalScrollCount); % Restrict the range of tolerance values to be from 0 to 0.15, which is the % useful range. tol = max(min(tol, 0.15), 0); % Call |reduce| with the specified tolerance. reduce(hfh,tol); hfh.UserData.tol = tol; % Update the ROI and turn all the points into waypoints to show the % density. hfh.Waypoints(:) = true; end
Удалите и создайте новый ROI Freehand с вложенными точками, чтобы сэкономить на пространстве.
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 with the new |Position| value. delete(hfh); drawfreehand(gca, 'Position', pos); end
bwareafilt
| bwboundaries
| drawfreehand
| Freehand