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
ROI blocks
Commits
f845c80d
Commit
f845c80d
authored
Jan 26, 2021
by
Stéphane DALLONGEVILLE
Browse files
Optimized ROI logical operation processing by caching BooleanMask object
parent
d4943cc5
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/main/java/plugins/stef/roi/bloc/op/LogicalOperationROI.java
View file @
f845c80d
package
plugins.stef.roi.bloc.op
;
import
java.lang.ref.SoftReference
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
icy.plugin.abstract_.Plugin
;
import
icy.plugin.interface_.PluginBundled
;
import
icy.plugin.interface_.PluginLibrary
;
import
icy.roi.BooleanMask2D
;
import
icy.roi.BooleanMask3D
;
import
icy.roi.ROI
;
import
icy.roi.ROI2D
;
import
icy.roi.ROI3D
;
import
icy.type.collection.CollectionUtil
;
import
plugins.adufour.blocks.tools.roi.ROIBlock
;
import
plugins.adufour.blocks.util.VarList
;
...
...
@@ -85,11 +92,53 @@ public class LogicalOperationROI extends Plugin implements ROIBlock, PluginLibra
boolean
copyRois
)
{
final
List
<
ROI
>
result
=
new
ArrayList
<
ROI
>();
final
Map
<
ROI
,
SoftReference
<
BooleanMask2D
>>
masks2d
=
new
HashMap
<>();
final
Map
<
ROI
,
SoftReference
<
BooleanMask3D
>>
masks3d
=
new
HashMap
<>();
try
{
for
(
ROI
roi
:
roiSetA
)
{
if
(
roi
instanceof
ROI2D
)
masks2d
.
put
(
roi
,
new
SoftReference
<>(((
ROI2D
)
roi
).
getBooleanMask
(
true
)));
else
if
(
roi
instanceof
ROI3D
)
masks3d
.
put
(
roi
,
new
SoftReference
<>(((
ROI3D
)
roi
).
getBooleanMask
(
true
)));
}
for
(
ROI
roi
:
roiSetB
)
{
if
(
roi
instanceof
ROI2D
)
masks2d
.
put
(
roi
,
new
SoftReference
<>(((
ROI2D
)
roi
).
getBooleanMask
(
true
)));
else
if
(
roi
instanceof
ROI3D
)
masks3d
.
put
(
roi
,
new
SoftReference
<>(((
ROI3D
)
roi
).
getBooleanMask
(
true
)));
}
}
catch
(
OutOfMemoryError
error
)
{
// not enough memory to build out the masks cache, we will use what we have...
}
for
(
ROI
roiA
:
roiSetA
)
{
SoftReference
<?>
ref
;
if
(
roiA
!=
null
)
{
BooleanMask2D
mask2dA
=
null
;
BooleanMask3D
mask3dA
=
null
;
// try to get masks from hashmap
ref
=
masks2d
.
get
(
roiA
);
if
(
ref
!=
null
)
mask2dA
=
(
BooleanMask2D
)
ref
.
get
();
else
{
ref
=
masks3d
.
get
(
roiA
);
if
(
ref
!=
null
)
mask3dA
=
(
BooleanMask3D
)
ref
.
get
();
}
boolean
cond
=
(
logicOp
==
LogicOperator
.
A_NOT_CONTAINED_IN_B
)
||
(
logicOp
==
LogicOperator
.
A_NOT_CONTAINING_B
)
||
(
logicOp
==
LogicOperator
.
A_NOT_INTERSECTING_B
);
...
...
@@ -97,12 +146,45 @@ public class LogicalOperationROI extends Plugin implements ROIBlock, PluginLibra
for
(
ROI
roiB
:
roiSetB
)
{
BooleanMask2D
mask2dB
=
null
;
BooleanMask3D
mask3dB
=
null
;
// try to get mask from hashmap
ref
=
masks2d
.
get
(
roiB
);
if
(
ref
!=
null
)
mask2dB
=
(
BooleanMask2D
)
ref
.
get
();
else
{
ref
=
masks3d
.
get
(
roiB
);
if
(
ref
!=
null
)
mask3dB
=
(
BooleanMask3D
)
ref
.
get
();
}
switch
(
logicOp
)
{
default
:
case
A_CONTAINED_IN_B:
case
A_NOT_CONTAINED_IN_B:
if
(
roiB
.
contains
(
roiA
))
// we have the 2D masks ? --> use them
if
((
mask2dA
!=
null
)
&&
(
mask2dB
!=
null
))
{
if
(
mask2dB
.
contains
(
mask2dA
))
{
done
=
true
;
cond
=
(
logicOp
==
LogicOperator
.
A_CONTAINED_IN_B
);
}
}
// we have the 3D masks ? --> use them
else
if
((
mask3dA
!=
null
)
&&
(
mask3dB
!=
null
))
{
if
(
mask3dB
.
contains
(
mask3dA
))
{
done
=
true
;
cond
=
(
logicOp
==
LogicOperator
.
A_CONTAINED_IN_B
);
}
}
// do the generic test
else
if
(
roiB
.
contains
(
roiA
))
{
done
=
true
;
cond
=
(
logicOp
==
LogicOperator
.
A_CONTAINED_IN_B
);
...
...
@@ -111,7 +193,26 @@ public class LogicalOperationROI extends Plugin implements ROIBlock, PluginLibra
case
A_CONTAINING_B:
case
A_NOT_CONTAINING_B:
if
(
roiA
.
contains
(
roiB
))
// we have the 2D masks ? --> use them
if
((
mask2dA
!=
null
)
&&
(
mask2dB
!=
null
))
{
if
(
mask2dA
.
contains
(
mask2dB
))
{
done
=
true
;
cond
=
(
logicOp
==
LogicOperator
.
A_CONTAINING_B
);
}
}
// we have the 3D masks ? --> use them
else
if
((
mask3dA
!=
null
)
&&
(
mask3dB
!=
null
))
{
if
(
mask3dA
.
contains
(
mask3dB
))
{
done
=
true
;
cond
=
(
logicOp
==
LogicOperator
.
A_CONTAINING_B
);
}
}
// do the generic test
else
if
(
roiA
.
contains
(
roiB
))
{
done
=
true
;
cond
=
(
logicOp
==
LogicOperator
.
A_CONTAINING_B
);
...
...
@@ -120,7 +221,26 @@ public class LogicalOperationROI extends Plugin implements ROIBlock, PluginLibra
case
A_INTERSECTING_B:
case
A_NOT_INTERSECTING_B:
if
(
roiA
.
intersects
(
roiB
))
// we have the 2D masks ? --> use them
if
((
mask2dA
!=
null
)
&&
(
mask2dB
!=
null
))
{
if
(
mask2dA
.
intersects
(
mask2dB
))
{
done
=
true
;
cond
=
(
logicOp
==
LogicOperator
.
A_INTERSECTING_B
);
}
}
// we have the 3D masks ? --> use them
else
if
((
mask3dA
!=
null
)
&&
(
mask3dB
!=
null
))
{
if
(
mask3dA
.
intersects
(
mask3dB
))
{
done
=
true
;
cond
=
(
logicOp
==
LogicOperator
.
A_INTERSECTING_B
);
}
}
// do the generic test
else
if
(
roiA
.
intersects
(
roiB
))
{
done
=
true
;
cond
=
(
logicOp
==
LogicOperator
.
A_INTERSECTING_B
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment