Создайте инструмент редактирования ROI от руки

В этом примере показано, как создать простой инструмент, чтобы отредактировать форму ROI от руки с помощью другого объекта ROI. По умолчанию объекты ROI От руки, images.roi.Freehand, уже включают подразумеваемые возможности, названные waypoints, для того, чтобы в интерактивном режиме отредактировать их форму. Путем перетаскивания любого из этих waypoints на ребре ROI можно настроить ребро ROI. Можно также добавить waypoints в интерактивном режиме в любую часть контура.

Другим способом отредактировать форму ROI От руки, предлагаемых многими популярными программами преобразования изображения, является инструмент 'кисти' или 'средство стирания'. Этот пример реализует один из этих инструментов, с помощью другого объекта ROI отредактировать ROI от руки.

Создайте ROI от руки

Создайте ROI От руки, который следует за формой маски сегментации. Для получения дополнительной информации об этом процессе смотрите Использование ROI От руки, чтобы Совершенствовать Маски Сегментации.

Считайте данные MRI в рабочую область.

im = dicomread('knee1.dcm');

Сегментируйте изображение MRI и выберите две самых больших области рисунка маски.

segmentedLabels = imsegkmeans(im,3);
boneMask = segmentedLabels==2;
boneMask = bwareafilt(boneMask, 1);

Получите координаты контуров двух сегментированных областей.

blocations = bwboundaries(boneMask,'noholes');

Отобразите изображение.

figure
hImage = imshow(im, []);

Преобразуйте местоположения, возвращенные bwboundaries к x, y порядок.

pos = blocations{1};
pos = fliplr(pos);

Создайте ROI от руки в сегментированной маске.

hf = drawfreehand('Position', pos);

Создайте инструмент редактирования ROI от руки

Создайте Круговой ROI, который будет использоваться в качестве средства стирания или инструмента редактирования ROI кисти. (Можно использовать любой images.roi.* классы путем создания небольшого изменения, упомянутого ниже).

he = images.roi.Circle(...
    'Center', [50 50],...
    'Radius', 10,...
    'Parent', gca,...
    'Color','r');

Сопоставьте два прослушивателя события с Круговым ROI. Каждый слушает для перемещения ROI, и другой слушает для того, когда перемещение останавливается. ROI, перемещающий функцию обратного вызова, пример убеждается, что имел свою привязку положения к пиксельным местоположениям и также изменил цвет (Красный/Зеленый), чтобы указать, удалит ли операция редактирования или добавит к целевому ROI от руки. Если ROI редактора прекращает перемещаться, мы создадим соответствующие бинарные маски для ROI редактора и целевого ROI от руки и сделаем необходимое редактирование. Наконец, мы преобразуем обновленную маску назад к объекту ROI от руки. Обеспечьте электричеством прослушиватель, чтобы реагировать каждый раз, когда этот ROI редактора перемещен

addlistener(he,'MovingROI', @(varargin)editorROIMoving(he, hf));
addlistener(he,'ROIMoved', @(varargin)editFreehand(hf, he));

В интерактивном режиме отредактируйте ROI от руки

Эта анимация показывает добавление, и удалите операцию редактирования.

Это - ROI, перемещающий функцию обратного вызова. Эта функция гарантирует, что привязки ROI редактора к пиксельной сетке, и изменяют цвет ROI редактора, чтобы указать, добавит ли это к ROI от руки или удалять область от ROI от руки. Если центр ROI редактора вне целевого ROI от руки, удаляет операцию, в противном случае это 'добавит'.

function editorROIMoving(he, hf)
% Snap editor ROI to grid
he.Position = round(he.Position);

% Check if the circle ROI's center is inside or outside the freehand ROI.
center = he.Center;
isAdd = hf.inROI(center(1), center(2));
if isAdd
    % Green if inside (since we will add to the freehand).
    he.Color = 'g';
else
    % Red otherwise.
    he.Color = 'r';
end
end

Это - редактирование коллбэк ROI от руки, который добавляет или удаляет область ROI редактора, который пересекает целевой ROI от руки.

function editFreehand(hf, he)

% Create a mask for the target freehand.
tmask = hf.createMask();
[m, n,~] = size(tmask);
% Include the boundary pixel locations
boundaryInd = sub2ind([m,n], hf.Position(:,2), hf.Position(:,1));
tmask(boundaryInd) = true;

% Create a mask from the editor ROI
emask = he.createMask();
boundaryInd = sub2ind([m,n], he.Position(:,2), he.Position(:,1));
emask(boundaryInd) = true;

% Check if center of the editor ROI is inside the target freehand. If you
% use a different editor ROI, ensure to update center computation.
center = he.Center; %
isAdd = hf.inROI(center(1), center(2));
if isAdd
    % Add the editor mask to the freehand mask
    newMask = tmask|emask;
else
    % Delete out the part of the freehand which intersects the editor
    newMask = tmask&~emask;
end

% Update the freehand ROI
perimPos = bwboundaries(newMask, 'noholes');
hf.Position = [perimPos{1}(:,2), perimPos{1}(:,1)];

end

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

| | | | | | | | |

Похожие темы