Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F61721122
MaskFactory.java
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, May 8, 13:31
Size
7 KB
Mime Type
text/x-java
Expires
Fri, May 10, 13:31 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
17549547
Attached To
R6269 BIOP Run Macro
MaskFactory.java
View Options
/*-
* #%L
* Fiji's plugin for colocalization analysis.
* %%
* Copyright (C) 2009 - 2017 Fiji developers.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
package
sc.fiji.coloc.gadgets
;
import
java.util.Arrays
;
import
net.imglib2.Cursor
;
import
net.imglib2.RandomAccess
;
import
net.imglib2.RandomAccessibleInterval
;
import
net.imglib2.img.ImgFactory
;
import
net.imglib2.img.array.ArrayImgFactory
;
import
net.imglib2.type.logic.BitType
;
import
net.imglib2.type.numeric.RealType
;
import
net.imglib2.view.Views
;
import
sc.fiji.coloc.algorithms.MissingPreconditionException
;
public
class
MaskFactory
{
public
enum
CombinationMode
{
AND
,
OR
,
NONE
}
/**
* Create a new mask image without any specific content, but with
* a defined size.
*/
public
static
RandomAccessibleInterval
<
BitType
>
createMask
(
long
[]
dim
)
{
ImgFactory
<
BitType
>
imgFactory
=
new
ArrayImgFactory
<
BitType
>();
return
imgFactory
.
create
(
dim
,
new
BitType
());
}
/**
* Create a new mask image with a defined size and preset content.
*/
public
static
RandomAccessibleInterval
<
BitType
>
createMask
(
long
[]
dim
,
boolean
val
)
{
RandomAccessibleInterval
<
BitType
>
mask
=
createMask
(
dim
);
for
(
BitType
t
:
Views
.
iterable
(
mask
))
t
.
set
(
val
);
return
mask
;
}
/**
* Create a new mask image with a defined size and preset content.
* @throws MissingPreconditionException
*/
public
static
RandomAccessibleInterval
<
BitType
>
createMask
(
long
[]
dim
,
long
[]
roiOffset
,
long
[]
roiDim
)
throws
MissingPreconditionException
{
if
(
dim
.
length
!=
roiOffset
.
length
||
dim
.
length
!=
roiDim
.
length
)
{
throw
new
MissingPreconditionException
(
"The dimensions of the mask as well as the ROIs and his offset must be the same."
);
}
final
RandomAccessibleInterval
<
BitType
>
mask
=
createMask
(
dim
);
final
int
dims
=
mask
.
numDimensions
();
final
long
[]
pos
=
new
long
[
dims
];
// create an array with the max corner of the ROI
final
long
[]
roiOffsetMax
=
new
long
[
dims
];
for
(
int
i
=
0
;
i
<
dims
;
++
i
)
roiOffsetMax
[
i
]
=
roiOffset
[
i
]
+
roiDim
[
i
];
// go through the mask and mask points as valid that are in the ROI
Cursor
<
BitType
>
cursor
=
Views
.
iterable
(
mask
).
localizingCursor
();
while
(
cursor
.
hasNext
()
)
{
cursor
.
fwd
();
cursor
.
localize
(
pos
);
boolean
valid
=
true
;
// test if the current position is contained in the ROI
for
(
int
i
=
0
;
i
<
dims
;
++
i
)
valid
&=
pos
[
i
]
>=
roiOffset
[
i
]
&&
pos
[
i
]
<
roiOffsetMax
[
i
];
cursor
.
get
().
set
(
valid
);
}
return
mask
;
}
/**
* Create a new mask based on a threshold condition for two images.
*/
public
static
<
T
extends
RealType
<
T
>>
RandomAccessibleInterval
<
BitType
>
createMask
(
RandomAccessibleInterval
<
T
>
ch1
,
RandomAccessibleInterval
<
T
>
ch2
,
T
threshold1
,
T
threshold2
,
ThresholdMode
tMode
,
CombinationMode
cMode
)
{
final
long
[]
dims
=
new
long
[
ch1
.
numDimensions
()
];
ch1
.
dimensions
(
dims
);
RandomAccessibleInterval
<
BitType
>
mask
=
createMask
(
dims
);
Cursor
<
T
>
cursor1
=
Views
.
iterable
(
ch1
).
cursor
();
Cursor
<
T
>
cursor2
=
Views
.
iterable
(
ch2
).
cursor
();
Cursor
<
BitType
>
maskCursor
=
Views
.
iterable
(
mask
).
cursor
();
while
(
cursor1
.
hasNext
()
&&
cursor2
.
hasNext
()
&&
maskCursor
.
hasNext
())
{
cursor1
.
fwd
();
cursor2
.
fwd
();
maskCursor
.
fwd
();
boolean
ch1Valid
,
ch2Valid
;
T
data1
=
cursor1
.
get
();
T
data2
=
cursor2
.
get
();
// get relation to threshold
if
(
tMode
==
ThresholdMode
.
Above
)
{
ch1Valid
=
data1
.
compareTo
(
threshold1
)
>
0
;
ch2Valid
=
data2
.
compareTo
(
threshold2
)
>
0
;
}
else
if
(
tMode
==
ThresholdMode
.
Below
)
{
ch1Valid
=
data1
.
compareTo
(
threshold1
)
<
0
;
ch2Valid
=
data2
.
compareTo
(
threshold2
)
<
0
;
}
else
{
throw
new
UnsupportedOperationException
();
}
BitType
maskData
=
maskCursor
.
get
();
// combine the results into mask
if
(
cMode
==
CombinationMode
.
AND
)
{
maskData
.
set
(
ch1Valid
&&
ch2Valid
);
}
else
if
(
cMode
==
CombinationMode
.
OR
)
{
maskData
.
set
(
ch1Valid
||
ch2Valid
);
}
else
if
(
cMode
==
CombinationMode
.
NONE
)
{
maskData
.
set
(
!(
ch1Valid
||
ch2Valid
)
);
}
else
{
throw
new
UnsupportedOperationException
();
}
}
return
mask
;
}
/**
* Creates a new mask of the given dimensions, based on the image data
* in the passed image. If the requested dimensionality is higher than
* what is available in the data, the data gets repeated in the higher
* dimensions.
*
* @param dim The dimensions of the new mask image
* @param origMask The image from which the mask should be created from
*/
public
static
<
T
extends
RealType
<
T
>>
RandomAccessibleInterval
<
BitType
>
createMask
(
final
long
[]
dim
,
final
RandomAccessibleInterval
<
T
>
origMask
)
{
final
RandomAccessibleInterval
<
BitType
>
mask
=
createMask
(
dim
);
final
long
[]
origDim
=
new
long
[
origMask
.
numDimensions
()
];
origMask
.
dimensions
(
origDim
);
// test if original mask and new mask have same dimensions
if
(
Arrays
.
equals
(
dim
,
origDim
))
{
// copy the input image to the mask output image
Cursor
<
T
>
origCursor
=
Views
.
iterable
(
origMask
).
localizingCursor
();
RandomAccess
<
BitType
>
maskCursor
=
mask
.
randomAccess
();
while
(
origCursor
.
hasNext
())
{
origCursor
.
fwd
();
maskCursor
.
setPosition
(
origCursor
);
boolean
value
=
origCursor
.
get
().
getRealDouble
()
>
0.001
;
maskCursor
.
get
().
set
(
value
);
}
}
else
if
(
dim
.
length
>
origDim
.
length
)
{
// sanity check
for
(
int
i
=
0
;
i
<
origDim
.
length
;
i
++)
{
if
(
origDim
[
i
]
!=
dim
[
i
])
throw
new
UnsupportedOperationException
(
"Masks with lower dimensionality than the image, "
+
" but a different extent are not yet supported."
);
}
// mask and image have different dimensionality and maybe even a different extent
Cursor
<
T
>
origCursor
=
Views
.
iterable
(
origMask
).
localizingCursor
();
RandomAccess
<
BitType
>
maskCursor
=
mask
.
randomAccess
();
final
long
[]
pos
=
new
long
[
origMask
.
numDimensions
()
];
// iterate over the original mask
while
(
origCursor
.
hasNext
())
{
origCursor
.
fwd
();
origCursor
.
localize
(
pos
);
boolean
value
=
origCursor
.
get
().
getRealDouble
()
>
0.001
;
// set available (lower dimensional) position information
for
(
int
i
=
0
;
i
<
origDim
.
length
;
i
++)
// setPosition requires first the position and then the dimension
maskCursor
.
setPosition
(
pos
[
i
],
i
);
// go through the missing dimensions and set the value
for
(
int
i
=
origDim
.
length
;
i
<
dim
.
length
;
i
++)
for
(
int
j
=
0
;
j
<
dim
[
i
];
j
++)
{
// setPosition requires first the position and then the dimension
maskCursor
.
setPosition
(
j
,
i
);
maskCursor
.
get
().
set
(
value
);
}
}
}
else
if
(
dim
.
length
<
origDim
.
length
)
{
// mask has more dimensions than image
throw
new
UnsupportedOperationException
(
"Masks with more dimensions than the image are not supported, yet."
);
}
else
{
// mask and image have a different extent, but are equal in dimensionality. Scale it?
throw
new
UnsupportedOperationException
(
"Masks with same dimensionality, but a different extent than the image are not supported, yet."
);
}
return
mask
;
}
}
Event Timeline
Log In to Comment