Mentions légales du service

Skip to content
Snippets Groups Projects
Commit df62d418 authored by DIB Elian's avatar DIB Elian
Browse files

Big Viewer revamp

parent 37569ad8
No related branches found
No related tags found
No related merge requests found
......@@ -2,34 +2,32 @@ classdef Viewer < handle
%VIEWER Summary of this class goes here
% Detailed explanation goes here
properties(SetObservable, AbortSet)
properties(SetObservable)
data
dims = 'xy'
name = 'LightField'
state = 'xy'
range = 'class'
curView = [1,1]
curPos = [1,1]
cv = [1,1]
cmap = gray
slice
clim
title
end
properties
h = []
im = []
ax = []
slices
end
properties(Dependent, Hidden)
range_
end
properties(Hidden)
classRange
currentRange
allRange
validStates = {'xy','uv','ux','vy','yx','vu','xu','yv'};
validRanges = {'class','current','all'};
statevec = logical([0,0,0,1,1]);
validDims = {'xy','uv','ux','vy','yx','vu','xu','yv'};
validRanges = {'class','slice','data'};
climClass
climData
gv
perm = [1,2,3,4,5]
maxView
end
methods
......@@ -37,9 +35,11 @@ classdef Viewer < handle
p = inputParser; p.StructExpand = true; p.KeepUnmatched = true;
p.addRequired('data');
p.addParameter('dims' , obj.dims ,@(dims) any(strcmpi(dims,obj.validDims)));
p.addParameter('name' , obj.name ,@ischar);
p.addParameter('state', obj.state ,@(state) any(strcmpi(state,obj.validStates)));
p.addParameter('range', obj.range ,@(range) any(strcmpi(range,obj.validRanges)));
p.addParameter('cv' , obj.cv ,@isnumeric);
p.addParameter('cmap' , obj.cmap ,@isnumeric);
p.parse(data,varargin{:});
......@@ -49,29 +49,24 @@ classdef Viewer < handle
obj.(fn) = res.(fn);
end
addlistener(obj, 'data' , 'PostSet', @(src,evnt) obj.updateSlices);
addlistener(obj, 'state' , 'PostSet', @(src,evnt) obj.updateSlices);
addlistener(obj, 'curView', 'PostSet', @(src,evnt) obj.updateFigure);
addlistener(obj, 'curPos' , 'PostSet', @(src,evnt) obj.updateFigure);
addlistener(obj, 'range' , 'PostSet', @(src,evnt) obj.updateFigure);
addlistener(obj, 'name' , 'PostSet', @(src,evnt) obj.updateFigure);
obj.updateData();
obj.updateDims();
obj.updateSlices();
obj.setRanges();
obj.view;
end
function range_ = get.range_(obj)
switch lower(obj.range)
case 'class'
range_ = obj.classRange;
case 'current'
u=obj.curView(1); v=obj.curView(2);
range_ = obj.currentRange{u,v};
case 'all'
range_ = obj.allRange;
otherwise
end
obj.updateSlice();
obj.updateCLim();
obj.updateTitle();
addlistener(obj, 'data' , 'PostSet', @(src,evnt) obj.updateData);
addlistener(obj, 'dims' , 'PostSet', @(src,evnt) obj.updateDims);
addlistener(obj, 'name' , 'PostSet', @(src,evnt) obj.updateName);
addlistener(obj, 'range', 'PostSet', @(src,evnt) obj.updateRange);
addlistener(obj, 'cv' , 'PostSet', @(src,evnt) obj.updateCV);
addlistener(obj, 'cmap' , 'PostSet', @(src,evnt) obj.updateCMap);
addlistener(obj, 'slice', 'PostSet', @(src,evnt) obj.updateSlice);
addlistener(obj, 'title', 'PostSet', @(src,evnt) obj.updateTitle);
addlistener(obj, 'clim' , 'PostSet', @(src,evnt) obj.updateCLim);
obj.view();
end
function view(obj)
......@@ -79,107 +74,165 @@ classdef Viewer < handle
obj.h = figure;
obj.ax = gca;
cv = num2cell(obj.curView);
obj.im = imagesc(obj.ax,obj.slices{cv{:}});
colormap gray; axis image;
obj.im = imagesc(obj.ax,obj.slice);
obj.ax.Colormap = obj.cmap;
axis(obj.ax,'image');
obj.h.KeyPressFcn = @obj.KeyPressCallback;
obj.h.WindowButtonDownFcn = @obj.ButtonDownCallback;
obj.h.WindowButtonUpFcn = @obj.ButtonUpCallback;
obj.updateFigure();
end
obj.updateFigure();
end
end
methods(Hidden)
function setRanges(obj)
obj.classRange = getrangefromclass(obj.data);
cMin = cellfun(@(slice) min(slice(:)),obj.slices);
cMax = cellfun(@(slice) max(slice(:)),obj.slices);
cMin(isnan(cMin)) = obj.classRange(1);
cMax(isnan(cMax)) = obj.classRange(2);
minmax = cMin>=cMax;
cMin(minmax) = cMax(minmax)-1;
cMax(minmax) = cMin(minmax)+1;
function updateData(obj)
if islogical(obj.data)
data_ = obj.data;
data_ = uint8(data_);
obj.data = [];
obj.data = data_;
end
obj.currentRange = arrayfun(@(a,b) [a,b],cMin,cMax,'UniformOutput',false);
obj.gv = arrayfun(@(x) 1:x,size(obj.data),'UniformOutput',false);
obj.climClass = getrangefromclass(obj.data);
obj.climData = [min(obj.data(:)) max(obj.data(:))];
obj.allRange = [min(cMin(:)) max(cMax(:))];
obj.updateCV();
end
function updateDims(obj)
obj.updatePerm();
obj.updateCV();
end
function updateSlices(obj)
switch lower(obj.state)
function updatePerm(obj)
switch lower(obj.dims)
case 'xu'
perm = [1,4,3,2,5];
obj.perm = [1,4,3,2,5];
case 'ux'
perm = [4,1,3,2,5];
obj.perm = [4,1,3,2,5];
case 'yv'
perm = [2,5,3,1,4];
obj.perm = [2,5,3,1,4];
case 'vy'
perm = [5,2,3,1,4];
obj.perm = [5,2,3,1,4];
case 'xy'
perm = [1,2,3,4,5];
obj.perm = [1,2,3,4,5];
case 'yx'
perm = [2,1,3,4,5];
obj.perm = [2,1,3,4,5];
case 'uv'
perm = [4,5,3,1,2];
obj.perm = [4,5,3,1,2];
case 'vu'
perm = [5,4,3,1,2];
obj.perm = [5,4,3,1,2];
end
end
function updateName(obj)
obj.updateTitle();
end
function updateRange(obj)
obj.updateCLim();
end
function updateCV(obj)
obj.maxView = arrayfun(@(x) size(obj.data,x),obj.perm(4:5));
obj.cv = min(obj.maxView,max([1,1],obj.cv));
obj.slices = LF.toSlices(permute(obj.data,perm));
obj.statevec = false(1,5);
obj.statevec(perm(4:5)) = true;
obj.updateTitle();
obj.updateSlice();
end
function updateFigure(obj)
function updateSlice(obj)
gv_ = obj.gv;
ccv = num2cell(obj.cv);
[gv_{obj.perm(4:5)}] = deal(ccv{:});
obj.slice = permute(obj.data(gv_{:}),obj.perm);
if obj.validFigure()
coordStr = {'x','y','c','u','v'};
coordStr(obj.statevec) = arrayfun(@num2str,obj.curView,'UniformOutput',false);
coordStr(~obj.statevec) = deal({':'});
coordStr = ['(' strjoin(coordStr,','),')'];
title_{1} = [obj.name ' ' coordStr];
title(title_);
cv = num2cell(obj.curView);
obj.im.CData = obj.slices{cv{:}};
obj.im.CData = obj.slice;
obj.im.AlphaData = double(any(~isnan(obj.im.CData),3));
obj.ax.CLim = obj.range_;
end
end
function updateCLim(obj)
switch lower(obj.range)
case 'class'
obj.clim = obj.climClass;
case 'slice'
obj.clim = [min(obj.slice(:)) max(obj.slice(:))];
case 'data'
obj.clim = obj.climData;
end
if diff(obj.clim)<=0
obj.clim(2) = obj.clim(1) + diff(getrangefromclass(obj.clim))/2;
end
if obj.validFigure()
obj.ax.CLim = obj.clim;
end
end
function updateTitle(obj)
coordVec = false(1,5);
coordVec(obj.perm(4:5)) = true;
coordStr = {'x','y','c','u','v'};
coordStr(coordVec) = arrayfun(@num2str,obj.cv,'UniformOutput',false);
coordStr(~coordVec) = deal({':'});
coordStr = ['(' strjoin(coordStr,','),')'];
obj.title = [obj.name,' ',coordStr];
if obj.validFigure()
obj.ax.Title.String = obj.title;
end
end
function updateCMap(obj)
if obj.validFigure()
obj.ax.Colormap = obj.cmap;
end
end
function updateFigure(obj)
if ~obj.validFigure()
return
end
obj.im.CData = obj.slice;
obj.im.AlphaData = double(any(~isnan(obj.im.CData),3));
obj.ax.CLim = obj.clim;
obj.ax.Title.String = obj.title;
obj.ax.Colormap = obj.cmap;
end
function KeyPressCallback(obj,~,evnt)
curView_ = obj.curView;
cv_ = obj.cv;
switch evnt.Key
case 'uparrow'
curView_(1) = curView_(1)-1;
cv_(1) = cv_(1)-1;
case 'downarrow'
curView_(1) = curView_(1)+1;
cv_(1) = cv_(1)+1;
case 'leftarrow'
curView_(2) = curView_(2)-1;
cv_(2) = cv_(2)-1;
case 'rightarrow'
curView_(2) = curView_(2)+1;
cv_(2) = cv_(2)+1;
case 'space'
rangeInd = find(strcmp(obj.range,obj.validRanges));
rangeInd = mod(rangeInd,3)+1;
obj.range = obj.validRanges{rangeInd};
end
sz = size(obj.slices);
obj.curView = min(sz,max([1,1],curView_));
obj.cv = min(obj.maxView,max([1,1],cv_));
end
function ButtonDownCallback(obj,~,~)
refView = obj.curView;
refView = obj.cv;
refPos = obj.ax.CurrentPoint(1,[2 1]);
obj.h.WindowButtonMotionFcn = ...
......@@ -191,24 +244,20 @@ classdef Viewer < handle
end
function ButtonMotionCallback(obj,~,~,refView,refPos)
axSize = [diff(obj.ax.YLim) diff(obj.ax.XLim)];
axSize = [diff(obj.ax.YLim),diff(obj.ax.XLim)];
axPos = obj.ax.CurrentPoint(1,[2,1]);
switch obj.h.SelectionType
case 'normal'
slicesSize = size(obj.slices);
mv = 2.*(axPos - refPos)./axSize.*slicesSize;
curView_ = refView + round(mv);
obj.curView = min(slicesSize,max([1,1],curView_));
mv = 2.*(axPos - refPos)./axSize.*obj.maxView;
cv_ = refView + round(mv);
obj.cv = min(obj.maxView,max([1,1],cv_));
case 'alt'
obj.curPos = flip(axPos);
end
end
function bool = validFigure(obj)
bool = ~isempty(obj.h) &&isvalid(obj.h) &&...
~isempty(obj.ax)&&isvalid(obj.ax)&&...
~isempty(obj.im)&&isvalid(obj.im);
bool = ~isempty(obj.im) && isvalid(obj.im);
end
end
end
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment