Skip to content

Commit df9c50a

Browse files
committed
add regionIsosurfaces.m
1 parent d70a42e commit df9c50a

File tree

2 files changed

+134
-3
lines changed

2 files changed

+134
-3
lines changed

src/@Image/isosurface.m

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
function varargout = isosurface(obj, isovalue, varargin)
2-
% Isosurface generation of a 3D image.
2+
% Generate isosurface of a 3D image.
33
%
44
% isosurface(IMG, ISOVALUE)
5-
% Computes isosurface from image data ans the specified isovalue.
5+
% Computes isosurface from image data and the specified isovalue.
66
% The functions simply consists in a wrapper to the "isosurface" function
77
% from Matlab.
88
%
@@ -15,14 +15,16 @@
1515

1616
% ------
1717
% Author: David Legland
18-
% e-mail: david.legland@inra.fr
18+
% e-mail: david.legland@inrae.fr
1919
% Created: 2010-12-16, using Matlab 7.9.0.529 (R2009b)
2020
% Copyright 2010 INRA - Cepia Software Platform.
2121

22+
% retrieve voxel coordinates in physical space
2223
x = getX(obj);
2324
y = getY(obj);
2425
z = getZ(obj);
2526

27+
% permute data to comply with Matlab orientation
2628
v = permute(obj.Data(:,:,:,1,1), [2 1 3]);
2729

2830
if nargout == 0

src/@Image/regionIsosurfaces.m

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
function [res, labels] = regionIsosurfaces(obj, varargin)
2+
% Generate isosurface of each region within a label image.
3+
%
4+
% MESHES = regionIsosurfaces(LBL)
5+
% Computes isosurfaces of each region within the label image LBL.
6+
%
7+
%
8+
% Example
9+
% markers = Image.true([50 50 50]);
10+
% n = 100;
11+
% rng(10);
12+
% seeds = randi(50, [n 3]);
13+
% for i = 1:n
14+
% markers(seeds(i,1), seeds(i,2), seeds(i,3)) = false;
15+
% end
16+
% wat = watershed(distanceMap(markers), 6);
17+
% wat2 = killBorders(wat);
18+
% figure; hold on; axis equal;
19+
% regionIsosurfaces(wat2, 'smoothRadius', 2, 'LineStyle', 'none');
20+
% view(3), light;
21+
%
22+
% See also
23+
% isosurface, gt
24+
%
25+
26+
% ------
27+
% Author: David Legland
28+
29+
% INRAE - BIA Research Unit - BIBS Platform (Nantes)
30+
% Created: 2021-02-22, using Matlab 9.8.0.1323502 (R2020a)
31+
% Copyright 2021 INRAE.
32+
33+
34+
%% Input arguiment processing
35+
36+
% check if labels are specified
37+
labels = [];
38+
if ~isempty(varargin) && size(varargin{1}, 2) == 1
39+
labels = varargin{1};
40+
varargin(1) = [];
41+
end
42+
43+
% extract the set of labels, without the background
44+
if isempty(labels)
45+
labels = findRegionLabels(obj);
46+
end
47+
nLabels = length(labels);
48+
49+
% parse other options
50+
smoothRadius = 0;
51+
siz = 0;
52+
if ~isempty(varargin) && strcmpi(varargin{1}, 'smoothRadius')
53+
smoothRadius = varargin{2};
54+
if isscalar(smoothRadius)
55+
smoothRadius = smoothRadius([1 1 1]);
56+
end
57+
siz = floor(smoothRadius * 2) + 1;
58+
varargin(1:2) = [];
59+
end
60+
61+
62+
%% Preprocessing
63+
64+
% retrieve voxel coordinates in physical space
65+
% (common to all labels)
66+
x = getX(obj);
67+
y = getY(obj);
68+
z = getZ(obj);
69+
70+
% permute data to comply with Matlab orientation
71+
v = permute(obj.Data(:,:,:,1,1), [2 1 3]);
72+
73+
% allocate memory for labels
74+
meshes = cell(1, nLabels);
75+
76+
77+
%% Isosurface computation
78+
79+
% iterate over regions to generate isosurfaces
80+
for iLabel = 1:nLabels
81+
label = labels(iLabel);
82+
83+
vol = double(v == label);
84+
% optional smoothing
85+
if smoothRadius > 0
86+
vol = filterData(vol, siz, smoothRadius);
87+
end
88+
89+
meshes{iLabel} = isosurface(x, y, z, vol, 0.5);
90+
end
91+
92+
93+
%% Finalization
94+
95+
if nargout == 0
96+
% display isosurfaces
97+
for i = 1:nLabels
98+
patch(meshes{i}, varargin{:});
99+
end
100+
101+
else
102+
% return computed mesh list
103+
res = meshes;
104+
end
105+
end
106+
107+
%% Utility function
108+
function data = filterData(data, kernelSize, sigma)
109+
% process each direction
110+
for i = 1:3
111+
% compute spatial reference
112+
refSize = (kernelSize(i) - 1) / 2;
113+
s0 = floor(refSize);
114+
s1 = ceil(refSize);
115+
lx = -s0:s1;
116+
117+
% compute normalized kernel
118+
sigma2 = 2*sigma(i).^2;
119+
kernel = exp(-(lx.^2 / sigma2));
120+
kernel = kernel / sum(kernel);
121+
122+
% reshape the kernel such as it is elongated in the i-th direction
123+
newDim = [ones(1, i-1) kernelSize(i) ones(1, 3-i)];
124+
kernel = reshape(kernel, newDim);
125+
126+
% apply filtering along one direction
127+
data = imfilter(data, kernel, 'replicate');
128+
end
129+
end

0 commit comments

Comments
 (0)