-
Nicola Vigano authored
Signed-off-by:
Nicola Vigano <nicola.vigano@esrf.fr>
Nicola Vigano authoredSigned-off-by:
Nicola Vigano <nicola.vigano@esrf.fr>
GtGuiThresholdGrain.m 8.59 KiB
classdef GtGuiThresholdGrain < GtVolView
properties
threshold = 0;
min_threshold = 0;
max_threshold = 1;
range = 1;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Public object API - Interaction with outside
methods
function obj = GtGuiThresholdGrain(vol, varargin)
viewer_args = varargin;
if ~ismember('f_title', varargin(1:2:end))
viewer_args(end+1:end+2) = {'f_title', 'Volume Segmentation'};
end
if ~ismember('overlay', varargin(1:2:end))
viewer_args(end+1:end+2) = {'overlay', vol};
end
obj = obj@GtVolView(vol, viewer_args{:});
end
function changeThreshold(obj, new_threshold)
obj.setThreshold(new_threshold);
set(obj.conf.h_thr_slider, 'Value', obj.threshold);
set(obj.conf.h_thr_edit, 'String', num2str(obj.threshold));
obj.updateDisplay();
end
function setSavingFunction(obj, func_handle)
obj.conf.save_func = func_handle;
end
function setSegmentFunction(obj, func_handle)
obj.conf.segment_func = func_handle;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Internal methods - Addressable from derived classes
methods (Access = protected)
function setConfigInvariants(obj)
setConfigInvariants@GtVolView(obj);
obj.conf.transparency = 0.4;
end
function initParams(obj, arguments)
initParams@GtVolView(obj, arguments)
obj.min_threshold = min(obj.conf.vol(:));
obj.max_threshold = max(obj.conf.vol(:));
obj.range = obj.max_threshold - obj.min_threshold;
obj.threshold = obj.min_threshold;
end
function initGui(obj)
initGui@GtVolView(obj)
% Let's disable zoom, while configuring
zoomOp = zoom(obj.conf.h_figure);
zoomState = get(zoomOp, 'Enable');
zoom(obj.conf.h_figure, 'off');
obj.conf.main_t_boxes = uiextras.VBox('Parent', obj.conf.currentParent);
obj.conf.upper_t_boxes = uiextras.HBox('Parent', obj.conf.main_t_boxes);
obj.conf.center_t_boxes = uiextras.HBox('Parent', obj.conf.main_t_boxes);
set(obj.conf.main_t_boxes, 'Sizes', [20, -1]);
obj.conf.h_thr_label = uicontrol('Style', 'text', ...
'Parent', obj.conf.upper_t_boxes, ...
'HorizontalAlignment', 'left');
obj.conf.h_thr_edit = uicontrol('Style', 'edit', ...
'Parent', obj.conf.upper_t_boxes);
obj.conf.radio_boxes = uiextras.HBox('Parent', obj.conf.upper_t_boxes);
obj.conf.h_thr_apply = uicontrol('Parent', obj.conf.upper_t_boxes, ...
'Style', 'pushbutton', ...
'String', 'Segment');
obj.conf.h_thr_seed = uicontrol('Parent', obj.conf.upper_t_boxes, ...
'Style', 'text', ...
'String', '');
set(obj.conf.upper_t_boxes, 'Sizes', [250, 100, -1, 70, 140]);
obj.conf.slider_main_t_boxes = uiextras.VBox( ...
'Parent', obj.conf.center_t_boxes);
obj.conf.slider_contr_t_boxes = uiextras.HBox( ...
'Parent', obj.conf.slider_main_t_boxes);
obj.conf.sliders_t_boxes = uiextras.HBox( ...
'Parent', obj.conf.slider_main_t_boxes);
obj.conf.h_thr_slider = uicontrol('Style', 'slider', ...
'Parent', obj.conf.sliders_t_boxes);
obj.conf.h_viewer_panel = uipanel('BorderWidth', 4, ...
'BorderType', 'line', ...
'Parent', obj.conf.center_t_boxes);
set(obj.conf.main_boxes, 'Parent', obj.conf.h_viewer_panel);
set(obj.conf.slider_main_t_boxes, 'Sizes', [0, -1]);
set(obj.conf.center_t_boxes, 'Sizes', [20, -1]);
% Reset back the zoom to the previous state (before the inclusion)
set(zoomOp, 'Enable', zoomState);
end
function resetUiComponents(obj)
resetUiComponents@GtVolView(obj);
set(obj.conf.h_thr_slider, 'Min', obj.min_threshold, ...
'Max', obj.max_threshold, 'Value', obj.threshold, ...
'SliderStep', [0.005 0.05]);
label_str = ['Threshold [' num2str(obj.min_threshold) ', ' ...
num2str(obj.max_threshold) ']:'];
set(obj.conf.h_thr_label, 'String', label_str);
set(obj.conf.h_thr_edit, 'String', num2str(obj.threshold));
end
function addUICallbacks(obj)
addUICallbacks@GtVolView(obj)
obj.addUICallback(obj.conf.h_thr_slider, ...
'AdjustmentValueChangedCallback', ...
@(src, evt)movedSlider(obj), true);
obj.addUICallback(obj.conf.h_thr_apply, ...
'Callback', ...
@(src, evt)segment(obj), false);
obj.addUICallback(obj.conf.h_thr_edit, ...
'Callback', ...
@(src, evt)changeThreshold(obj, str2double(get(obj.conf.h_thr_edit, 'String'))), false);
end
function setVisualisedData(obj, image, vol, is_overlay)
slice = obj.loadSlice(vol);
if (is_overlay)
slice = slice > obj.threshold;
zero_slice = zeros(size(slice));
slice(:, :, 2) = zero_slice;
slice(:, :, 3) = zero_slice;
else
slice_max = get(obj.conf.h_max, 'Value');
slice_min = get(obj.conf.h_min, 'Value');
slice = (slice - slice_min)/(slice_max - slice_min);
slice(slice > 1) = 1;
slice(slice < 0) = 0;
slice = repmat(slice, [1,1,3]);
end
set(image, 'cdata', slice);
end
function createAxesMenu(obj)
createAxesMenu@GtVolView(obj);
obj.conf.h_menu_items{end+1} = uimenu(obj.conf.h_context_menu, ...
'Label', 'Set as seed (Morpho)', ...
'Callback', @(src,evt)setSeed(obj));
end
function guiQuit(obj)
if (isfield(obj.conf, 'save_func'))
obj.conf.save_func(obj.threshold);
end
guiQuit@GtVolView(obj);
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Public Callbacks - Interaction with GUI elements
methods (Access = public)
function updateBC(obj)
updateBC@GtVolView(obj);
obj.setVisualisedData(obj.conf.h_im, obj.conf.vol, false);
end
function movedSlider(obj)
new_thresh = get(obj.conf.h_thr_slider, 'Value');
set(obj.conf.h_thr_edit, 'String', num2str(obj.threshold));
obj.setThreshold(new_thresh);
obj.updateDisplay();
end
function segment(obj)
if (isfield(obj.conf, 'segment_func'))
if (isfield(obj.conf, 'morpho') && ~isempty(obj.conf.morpho))
obj.conf.segment_func(obj.threshold, obj.conf.morpho);
else
obj.conf.segment_func(obj.threshold, 0);
end
else
errordlg('No segmentation function assigned', 'Segment');
end
end
function setSeed(obj, point)
if (~exist('point', 'var'))
point = obj.conf.clicked_point;
end
voxel = round(point);
obj.conf.morpho = voxel;
set(obj.conf.h_thr_seed, 'String', sprintf('Seed: (%d, %d, %d)', voxel));
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Very internal methods - Private for this class
methods (Access = protected)
function setThreshold(obj, new_threshold)
obj.threshold = new_threshold;
if (obj.threshold > obj.max_threshold)
obj.threshold = obj.max_threshold;
elseif (obj.threshold < obj.min_threshold)
obj.threshold = obj.min_threshold;
end
end
end
end