Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Bioimage Analysis
Active Contour
Commits
f5df793f
Commit
f5df793f
authored
Jan 29, 2020
by
Daniel Felipe GONZALEZ OBANDO
Browse files
enabled volume constraint in Plugin GUI
parent
4be794ba
Changes
2
Show whitespace changes
Inline
Side-by-side
.gitignore
View file @
f5df793f
bin
pluginfile-active-contours*.jar
/ActiveContours.jar
src/plugins/adufour/activecontours/ActiveContours.java
View file @
f5df793f
...
...
@@ -80,33 +80,26 @@ import plugins.kernel.roi.roi3d.ROI3DStack;
import
plugins.nchenouard.spot.Detection
;
import
vtk.vtkObjectBase
;
public
class
ActiveContours
extends
EzPlug
implements
EzStoppable
,
Block
{
public
class
ActiveContours
extends
EzPlug
implements
EzStoppable
,
Block
{
public
static
final
String
CONTOUR_BASE_NAME
=
"Contour #"
;
public
static
final
String
CONTOUR_ID
=
"contourId"
;
private
class
LocalRegionStatisticsComputer
implements
Callable
<
Object
>
{
private
class
LocalRegionStatisticsComputer
implements
Callable
<
Object
>
{
final
ActiveContour
contour
;
final
boolean
maskBased
;
public
LocalRegionStatisticsComputer
(
ActiveContour
contour
,
boolean
maskBased
)
{
public
LocalRegionStatisticsComputer
(
ActiveContour
contour
,
boolean
maskBased
)
{
this
.
contour
=
contour
;
this
.
maskBased
=
maskBased
;
}
@Override
public
Object
call
()
{
try
{
public
Object
call
()
{
try
{
double
cin
=
contour
.
computeAverageIntensity
(
contour
instanceof
Mesh3D
?
regionData
:
regionDataSummed
,
maskBased
?
contourMask_buffer
:
null
);
region_cin
.
put
(
trackGroup
.
getValue
().
getTrackSegmentWithDetection
(
contour
),
cin
);
}
catch
(
TopologyException
topo
)
{
}
catch
(
TopologyException
topo
)
{
System
.
err
.
println
(
"Removing a contour. Reason: "
+
topo
.
getMessage
());
allContoursAtTimeT
.
remove
(
contour
);
evolvingContoursAtTimeT
.
remove
(
contour
);
...
...
@@ -115,18 +108,15 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
}
}
private
class
LocalBackgroundStatisticsComputer
implements
Callable
<
Object
>
{
private
class
LocalBackgroundStatisticsComputer
implements
Callable
<
Object
>
{
final
ActiveContour
contour
;
public
LocalBackgroundStatisticsComputer
(
ActiveContour
contour
)
{
public
LocalBackgroundStatisticsComputer
(
ActiveContour
contour
)
{
this
.
contour
=
contour
;
}
@Override
public
Object
call
()
{
public
Object
call
()
{
TrackSegment
segment
=
trackGroup
.
getValue
().
getTrackSegmentWithDetection
(
contour
);
double
cout
=
contour
.
computeBackgroundIntensity
(
regionData
,
contourMask_buffer
);
...
...
@@ -137,8 +127,7 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
}
}
private
class
ContourInitializer
implements
Callable
<
Object
>
{
private
class
ContourInitializer
implements
Callable
<
Object
>
{
final
ROI
roi
;
final
int
z
;
final
int
t
;
...
...
@@ -148,8 +137,7 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
final
List
<
TrackSegment
>
endedTracks
;
public
ContourInitializer
(
ROI
roi
,
int
z
,
int
t
,
Tuple3d
pixelSize
,
int
convWinSize
,
List
<
TrackSegment
>
activeTracks
,
List
<
TrackSegment
>
justEndedTracks
)
{
List
<
TrackSegment
>
activeTracks
,
List
<
TrackSegment
>
justEndedTracks
)
{
super
();
this
.
roi
=
roi
;
...
...
@@ -161,9 +149,9 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
this
.
endedTracks
=
justEndedTracks
;
}
// test if the object is colliding an existing contour or if we need to discard
it for other reason
private
boolean
colliding
()
{
// test if the object is colliding an existing contour or if we need to discard
// it for other reason
private
boolean
colliding
()
{
// // image bounds
// final Rectangle imageBounds = inputData.getBounds2D();
// // minus one (to detect object on border)
...
...
@@ -173,8 +161,7 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
// imageBounds.height -= 2;
// test if object is intersecting with current active contours
for
(
TrackSegment
segment
:
activeTracks
)
{
for
(
TrackSegment
segment
:
activeTracks
)
{
// get contour for this active track
final
ActiveContour
contour
=
(
ActiveContour
)
segment
.
getLastDetection
();
// get ROI from contour
...
...
@@ -189,8 +176,7 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
}
@Override
public
Object
call
()
{
public
Object
call
()
{
// object colliding active contours ? --> discard it
if
(
colliding
())
return
null
;
...
...
@@ -202,15 +188,13 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
return
null
;
// does it overlap with a track that terminates in the previous frame?
for
(
TrackSegment
track
:
endedTracks
)
{
for
(
TrackSegment
track
:
endedTracks
)
{
final
ActiveContour
previousContour
=
(
ActiveContour
)
track
.
getLastDetection
();
// get ROI from contour
final
ROI
previousContourROI
=
previousContour
.
toROI
(
ROIType
.
POLYGON
,
null
);
// object is intersecting previous contour ?
if
(
roi
.
intersects
(
previousContourROI
))
{
if
(
roi
.
intersects
(
previousContourROI
))
{
System
.
out
.
println
(
"Found link at time "
+
t
+
", position ("
+
contour
.
getX
()
+
";"
+
contour
.
getY
()
+
")"
);
// add contour to the track
...
...
@@ -230,14 +214,12 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
}
}
private
class
ContourDuplicator
implements
Callable
<
Object
>
{
private
class
ContourDuplicator
implements
Callable
<
Object
>
{
final
TrackSegment
segment
;
final
int
t
;
final
int
convWinSize
;
public
ContourDuplicator
(
TrackSegment
segment
,
int
t
,
int
convWinSize
)
{
public
ContourDuplicator
(
TrackSegment
segment
,
int
t
,
int
convWinSize
)
{
super
();
this
.
segment
=
segment
;
...
...
@@ -246,8 +228,7 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
}
@Override
public
Object
call
()
{
public
Object
call
()
{
Detection
detection
;
detection
=
segment
.
getDetectionAtTime
(
t
);
...
...
@@ -308,19 +289,16 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
public
final
EzVarDouble
convergence_criterion
=
new
EzVarDouble
(
"Convergence criterion"
,
0.001
,
0
,
1
,
0.0001
);
public
final
EzVarInteger
convergence_nbIter
=
new
EzVarInteger
(
"Max. iterations"
,
100000
,
100
,
100000
,
1000
);
public
enum
ExportROI
{
public
enum
ExportROI
{
NO
,
ON_INPUT
,
ON_NEW_IMAGE
,
AS_LABELS
}
public
enum
ROIType
{
public
enum
ROIType
{
AREA
(
ROI2DArea
.
class
),
POLYGON
(
ROI2DPolygon
.
class
);
final
Class
<?
extends
ROI
>
clazz
;
private
ROIType
(
Class
<?
extends
ROI
>
clazz
)
{
private
ROIType
(
Class
<?
extends
ROI
>
clazz
)
{
this
.
clazz
=
clazz
;
}
}
...
...
@@ -339,7 +317,7 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
private
final
HashMap
<
TrackSegment
,
Double
>
volumes
=
new
HashMap
<
TrackSegment
,
Double
>();
public
final
EzVarBoolean
volume_constraint
=
new
EzVarBoolean
(
"Volume constraint"
,
false
);
public
final
EzVarDouble
volume_weight
=
new
EzVarDouble
(
"Volume weight"
,
0.01
,
0
,
1
,
0.01
);
public
final
EzVarDouble
volume_weight
=
new
EzVarDouble
(
"Volume weight"
,
0.01
,
0
,
1
,
0.
0
01
);
public
final
EzButton
showTrackManager
;
...
...
@@ -375,22 +353,17 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
private
long
lastVtkGCTime
=
0L
;
public
ActiveContours
()
{
public
ActiveContours
()
{
super
();
multiThreadService
.
setThreadName
(
"Active Contours"
);
showTrackManager
=
new
EzButton
(
"Send to track manager"
,
new
ActionListener
()
{
showTrackManager
=
new
EzButton
(
"Send to track manager"
,
new
ActionListener
()
{
@Override
public
void
actionPerformed
(
ActionEvent
e
)
{
ThreadUtil
.
invokeLater
(
new
Runnable
()
{
public
void
actionPerformed
(
ActionEvent
e
)
{
ThreadUtil
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
public
void
run
()
{
if
(
trackGroup
.
getValue
()
==
null
)
return
;
if
(
trackGroup
.
getValue
().
getTrackSegmentList
().
isEmpty
())
...
...
@@ -406,14 +379,12 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
});
}
public
TrackGroup
getTrackGroup
()
{
public
TrackGroup
getTrackGroup
()
{
return
trackGroup
.
getValue
();
}
@Override
public
void
initialize
()
{
public
void
initialize
()
{
addEzComponent
(
showAdvancedOptions
);
addEzComponent
(
input
);
...
...
@@ -500,27 +471,25 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
tracking
.
addVisibilityTriggerTo
(
tracking_newObjects
,
true
);
addEzComponent
(
volume_constraint
);
tracking
.
addVisibilityTriggerTo
(
volume_constraint
,
true
);
addEzComponent
(
volume_weight
);
volume_constraint
.
addVisibilityTriggerTo
(
volume_weight
,
true
);
addEzComponent
(
showTrackManager
);
setTimeDisplay
(
true
);
// TODO: we disabled volume constraint feature as it doesn't work and sometime end to crazy contour (Stephane)
volume_constraint
.
setValue
(
Boolean
.
FALSE
);
volume_constraint
.
setEnabled
(
false
);
}
@Override
public
void
loadParameters
(
File
file
)
{
public
void
loadParameters
(
File
file
)
{
super
.
loadParameters
(
file
);
// TODO: disabled as the feature is broken (Stephane)
volume_constraint
.
setValue
(
Boolean
.
FALSE
);
}
@Override
public
void
execute
()
{
public
void
execute
()
{
output_labels
.
setValue
(
null
);
volumes
.
clear
();
roiOutput
.
setValue
(
null
);
...
...
@@ -545,7 +514,8 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
tracks
.
setDescription
(
"Active contours ("
+
new
Date
().
toString
()
+
")"
);
trackGroup
.
setValue
(
tracks
);
// initialize the mask buffer once (used to calculate average intensities inside/outside)
// initialize the mask buffer once (used to calculate average intensities
// inside/outside)
final
Rectangle3D
.
Integer
bounds3d
=
inputData
.
getBounds5D
().
toRectangle3D
().
toInteger
();
final
Rectangle
bounds2d
=
inputData
.
getBounds2D
();
final
BooleanMask2D
[]
maskSlices
=
new
BooleanMask2D
[
bounds3d
.
sizeZ
];
...
...
@@ -555,11 +525,9 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
contourMask_buffer
=
new
BooleanMask3D
(
bounds3d
,
maskSlices
);
if
(!
Icy
.
getMainInterface
().
isHeadLess
())
{
if
(!
Icy
.
getMainInterface
().
isHeadLess
())
{
// replace any ActiveContours Painter object on the sequence by ours
for
(
Overlay
existingOverlay
:
inputData
.
getOverlays
())
{
for
(
Overlay
existingOverlay
:
inputData
.
getOverlays
())
{
if
(
existingOverlay
instanceof
ActiveContoursOverlay
)
existingOverlay
.
remove
();
}
...
...
@@ -577,18 +545,13 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
ROI
field
=
null
;
final
Sequence
boundSource
=
evolution_bounds
.
getValue
();
if
(
boundSource
!=
null
)
{
if
(
boundSource
!=
null
)
{
final
List
<
ROI
>
rois
=
boundSource
.
getROIs
();
if
(
rois
.
size
()
>
0
)
{
try
{
if
(
rois
.
size
()
>
0
)
{
try
{
field
=
ROIUtil
.
merge
(
rois
,
BooleanOperator
.
OR
);
}
catch
(
UnsupportedOperationException
e
)
{
}
catch
(
UnsupportedOperationException
e
)
{
throw
new
VarException
(
evolution_bounds
.
getVariable
(),
"Cannot compute the evolution bounds: "
+
e
.
getMessage
()
+
"\nIf you are not sure how to fix this, change this parameter to \"No Sequence\""
);
...
...
@@ -597,12 +560,10 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
}
// no specific field ? limit to sequence bounds
if
(
field
==
null
)
{
if
(
field
==
null
)
{
if
(
inputData
.
getSizeZ
()
==
1
)
field
=
new
ROI2DRectangle
(
0
,
0
,
inputData
.
getWidth
(),
inputData
.
getHeight
());
else
{
else
{
final
ROI3DStack
<
ROI2DRectangle
>
field3D
=
new
ROI3DStack
<
ROI2DRectangle
>(
ROI2DRectangle
.
class
);
for
(
int
z
=
0
;
z
<
inputData
.
getSizeZ
()
-
1
;
z
++)
...
...
@@ -612,11 +573,11 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
}
}
for
(
int
t
=
startT
;
t
<=
endT
;
t
++)
{
for
(
int
t
=
startT
;
t
<=
endT
;
t
++)
{
int
iteration
;
// if sizeT changed during AC processing (i already did it to shorthen processing time :p)
// if sizeT changed during AC processing (i already did it to shorthen
// processing time :p)
if
(
t
>=
inputData
.
getSizeT
())
break
;
...
...
@@ -676,27 +637,21 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
int
maxId
=
0
;
// get maximum id
for
(
ROI
roi
:
roiOutput
.
getValue
())
{
try
{
for
(
ROI
roi
:
roiOutput
.
getValue
())
{
try
{
// get object id
final
int
contourId
=
Integer
.
parseInt
(
roi
.
getProperty
(
CONTOUR_ID
));
if
(
contourId
>
maxId
)
maxId
=
contourId
;
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
// ignore
}
}
// then fix ROI names
final
int
nbPaddingDigits
=
(
int
)
Math
.
floor
(
Math
.
log10
(
maxId
));
for
(
ROI
roi
:
roiOutput
.
getValue
())
{
try
{
for
(
ROI
roi
:
roiOutput
.
getValue
())
{
try
{
// get object id
final
int
contourId
=
Integer
.
parseInt
(
roi
.
getProperty
(
CONTOUR_ID
));
final
String
roiName
=
roi
.
getName
();
...
...
@@ -706,19 +661,15 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
else
roi
.
setName
(
CONTOUR_BASE_NAME
+
StringUtil
.
toString
(
contourId
,
nbPaddingDigits
)
+
" ("
+
roiName
+
")"
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
// ignore
}
}
if
(
getUI
()
!=
null
)
{
if
(
getUI
()
!=
null
)
{
Sequence
out
=
inputData
;
switch
(
output_rois
.
getValue
())
{
switch
(
output_rois
.
getValue
())
{
case
ON_NEW_IMAGE:
out
=
SequenceUtil
.
getCopy
(
inputData
);
out
.
setName
(
inputData
.
getName
()
+
" + Active contours"
);
...
...
@@ -760,23 +711,17 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
regionDataSummed
=
null
;
}
boolean
executeMultiThread
(
Collection
<
Callable
<
Object
>>
tasks
,
String
messageOnError
)
throws
Exception
{
try
{
boolean
executeMultiThread
(
Collection
<
Callable
<
Object
>>
tasks
,
String
messageOnError
)
throws
Exception
{
try
{
// force wait completion for all tasks
for
(
Future
<
Object
>
res
:
multiThreadService
.
invokeAll
(
tasks
))
res
.
get
();
return
true
;
}
catch
(
InterruptedException
e
)
{
}
catch
(
InterruptedException
e
)
{
// restore the interrupted flag
Thread
.
currentThread
().
interrupt
();
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
if
(
StringUtil
.
isEmpty
(
messageOnError
))
throw
e
;
...
...
@@ -787,8 +732,7 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
return
false
;
}
private
void
initData
(
int
t
)
{
private
void
initData
(
int
t
)
{
final
int
edgeChannel
=
edge_c
.
getValue
().
intValue
();
final
int
regionChannel
=
region_c
.
getValue
().
intValue
();
...
...
@@ -819,39 +763,33 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
regionData
=
new
Sequence
(
OMEUtil
.
createOMEXMLMetadata
(
inputData
.
getOMEXMLMetadata
()),
"region data"
);
// convert float data rescaled to [0..1]
for
(
int
z
=
0
;
z
<
bounds
.
sizeZ
;
z
++)
{
for
(
int
z
=
0
;
z
<
bounds
.
sizeZ
;
z
++)
{
IcyBufferedImage
img
;
img
=
currentFrame
.
getImage
(
0
,
z
,
edgeChannel
);
img
=
IcyBufferedImageUtil
.
convertType
(
img
,
DataType
.
FLOAT
,
new
Scaler
[]
{
edgeScaler
});
img
=
IcyBufferedImageUtil
.
convertType
(
img
,
DataType
.
FLOAT
,
new
Scaler
[]
{
edgeScaler
});
edgeData
.
setImage
(
0
,
z
,
img
);
img
=
currentFrame
.
getImage
(
0
,
z
,
regionChannel
);
img
=
IcyBufferedImageUtil
.
convertType
(
img
,
DataType
.
FLOAT
,
new
Scaler
[]
{
regionScaler
});
img
=
IcyBufferedImageUtil
.
convertType
(
img
,
DataType
.
FLOAT
,
new
Scaler
[]
{
regionScaler
});
regionData
.
setImage
(
0
,
z
,
img
);
}
try
{
try
{
// smooth the signal
Sequence
gaussian
=
Kernels1D
.
CUSTOM_GAUSSIAN
.
createGaussianKernel1D
(
1
).
toSequence
();
Convolution1D
.
convolve
(
edgeData
,
gaussian
,
gaussian
,
null
);
Convolution1D
.
convolve
(
regionData
,
gaussian
,
gaussian
,
null
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
"Warning: error while smoothing the signal: "
+
e
.
getMessage
());
}
// summed region data (use to accelerate intensity calculations)
regionDataSummed
=
SequenceUtil
.
getCopy
(
regionData
);
for
(
int
z
=
0
;
z
<
bounds
.
sizeZ
;
z
++)
{
for
(
int
z
=
0
;
z
<
bounds
.
sizeZ
;
z
++)
{
final
float
[]
regionDataSliceSummed
=
regionDataSummed
.
getDataXYAsFloat
(
0
,
z
,
0
);
for
(
int
j
=
0
;
j
<
bounds
.
sizeY
;
j
++)
{
for
(
int
j
=
0
;
j
<
bounds
.
sizeY
;
j
++)
{
// start at the second pixel (index 1) of each line
int
offset
=
(
j
*
bounds
.
sizeX
)
+
1
;
...
...
@@ -865,31 +803,27 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
}
}
private
void
initCurrentContours
(
final
int
t
)
{
private
void
initCurrentContours
(
final
int
t
)
{
// prepare parameters
final
int
convWinSize
=
convergence_winSize
.
getValue
().
intValue
()
*
2
;
// use multi threading to initiate current contours (by duplicating ones from previous frame)
// use multi threading to initiate current contours (by duplicating ones from
// previous frame)
final
List
<
Callable
<
Object
>>
tasks
=
new
ArrayList
<
Callable
<
Object
>>();
try
{
try
{
// duplicate contours from the previous frame
for
(
TrackSegment
segment
:
trackGroup
.
getValue
().
getTrackSegmentList
())
tasks
.
add
(
new
ContourDuplicator
(
segment
,
t
,
convWinSize
));
// execute tasks
executeMultiThread
(
tasks
,
"couldn't duplicate a contour"
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
System
.
err
.
println
(
"Warning: (reason: "
+
e
.
getMessage
()
+
"). Moving on..."
);
}
}
private
void
addNewContours
(
final
int
t
)
{
private
void
addNewContours
(
final
int
t
)
{
// prepare parameters
final
TrackGroup
tg
=
trackGroup
.
getValue
();
final
List
<
TrackSegment
>
tracks
=
trackGroup
.
getValue
().
getTrackSegmentList
();
...
...
@@ -910,47 +844,38 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
final
List
<
Callable
<
Object
>>
tasks
=
new
ArrayList
<
Callable
<
Object
>>();
final
List
<
TrackSegment
>
newTracks
=
new
ArrayList
<
TrackSegment
>();
try
{
try
{
// initialize new contours
for
(
ROI
roi
:
objects
)
tasks
.
add
(
new
ContourInitializer
(
roi
,
currentZ
,
t
,
pixelSize
,
convWinSize
,
activeTracks
,
justEndedTracks
));
// force wait completion for all tasks
for
(
Future
<
Object
>
res
:
multiThreadService
.
invokeAll
(
tasks
))
{
for
(
Future
<
Object
>
res
:
multiThreadService
.
invokeAll
(
tasks
))
{
final
TrackSegment
track
=
(
TrackSegment
)
res
.
get
();
// a new track was created ? --> add it
if
(
track
!=
null
)
newTracks
.
add
(
track
);
}
}
catch
(
InterruptedException
e
)
{
}
catch
(
InterruptedException
e
)
{
// restore the interrupted flag
Thread
.
currentThread
().
interrupt
();
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
System
.
err
.
println
(
"Warning: couldn't initialize a contour (reason: "
+
e
.
getMessage
()
+
")."
);
}
// add new created tracks
synchronized
(
tg
)
{
synchronized
(
tg
)
{
for
(
TrackSegment
track
:
newTracks
)
tg
.
addTrackSegment
(
track
);
}
synchronized
(
region_cin
)
{
synchronized
(
region_cin
)
{
for
(
TrackSegment
track
:
newTracks
)
region_cin
.
put
(
track
,
Double
.
valueOf
(
0
d
));
}
synchronized
(
region_cout
)
{
synchronized
(
region_cout
)
{
for
(
TrackSegment
track
:
newTracks
)
region_cout
.
put
(
track
,
Double
.
valueOf
(
0
d
));
}
...
...
@@ -959,14 +884,11 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
/**
* Returns all {@link TrackSegment} ending at the specified time point
*/
private
List
<
TrackSegment
>
getTracksEndingAt
(
List
<
TrackSegment
>
tracks
,
int
t
)
{
private
List
<
TrackSegment
>
getTracksEndingAt
(
List
<
TrackSegment
>
tracks
,
int
t
)
{
final
List
<
TrackSegment
>
result
=
new
ArrayList
<
TrackSegment
>();
if
(
t
>=
0
)
{
for
(
TrackSegment
track
:
tracks
)
{
if
(
t
>=
0
)
{
for
(
TrackSegment
track
:
tracks
)
{
// get last detection for this track
final
Detection
detection
=
track
.
getLastDetection
();
...
...
@@ -979,13 +901,11 @@ public class ActiveContours extends EzPlug implements EzStoppable, Block
return
result
;
}
private
List
<
ROI
>
getRoisOf
(
int
t
)
{
private
List
<
ROI
>
getRoisOf
(
int
t
)
{
List
<
ROI
>
result
=
CollectionUtil
.
asArrayList
(
roiInput
.
getValue
());
// protocol mode, no ROI ? --> cannot continue
if
(
result
.
isEmpty
())
{