Skip to content

Commit 0894c41

Browse files
committed
An action to export tracking results to a label image.
This action creates a label image from the tracking results. " A new 16-bit image is generated, of same dimension and size that of the input image. The label image has one channel, with black baground (0 value) everywhere, except where there are spots. Each spot is painted with a uniform integer value equal to the trackID it belongs to. Spots that do not belong to tracks are painted with a unique integer larger than the last trackID in the dataset. Only visible spots are painted.
1 parent 00b871a commit 0894c41

2 files changed

Lines changed: 187 additions & 0 deletions

File tree

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
package fiji.plugin.trackmate.action;
2+
3+
import java.util.Set;
4+
import java.util.concurrent.atomic.AtomicInteger;
5+
6+
import javax.swing.ImageIcon;
7+
8+
import org.scijava.plugin.Plugin;
9+
10+
import fiji.plugin.trackmate.Model;
11+
import fiji.plugin.trackmate.Spot;
12+
import fiji.plugin.trackmate.TrackMate;
13+
import fiji.plugin.trackmate.gui.TrackMateGUIController;
14+
import fiji.plugin.trackmate.gui.TrackMateWizard;
15+
import fiji.plugin.trackmate.util.SpotNeighborhood;
16+
import ij.ImagePlus;
17+
import net.imagej.ImgPlus;
18+
import net.imagej.axis.Axes;
19+
import net.imagej.axis.AxisType;
20+
import net.imglib2.Dimensions;
21+
import net.imglib2.FinalDimensions;
22+
import net.imglib2.img.Img;
23+
import net.imglib2.img.display.imagej.ImageJFunctions;
24+
import net.imglib2.meta.view.HyperSliceImgPlus;
25+
import net.imglib2.type.numeric.integer.UnsignedShortType;
26+
import net.imglib2.util.Util;
27+
28+
@SuppressWarnings( "deprecation" )
29+
public class LabelImgExporter extends AbstractTMAction
30+
{
31+
32+
public static final String INFO_TEXT = "<html>"
33+
+ "This action creates a label image from the tracking results. "
34+
+ "<p> "
35+
+ "A new 16-bit image is generated, of same dimension and size that "
36+
+ "of the input image. The label image has one channel, with black baground (0 value) "
37+
+ "everywhere, except where there are spots. Each spot is painted with "
38+
+ "a uniform integer value equal to the trackID it belongs to. "
39+
+ "Spots that do not belong to tracks are painted with a unique integer "
40+
+ "larger than the last trackID in the dataset. "
41+
+ "<p> "
42+
+ "Only visible spots are painted. "
43+
+ "</html>";
44+
45+
public static final String KEY = "EXPORT_LABEL_IMG";
46+
47+
public static final ImageIcon ICON = new ImageIcon( TrackMateWizard.class.getResource( "images/picture_key.png" ) );
48+
49+
public static final String NAME = "Export label image";
50+
51+
@Override
52+
public void execute( final TrackMate trackmate )
53+
{
54+
createLabelImagePlus( trackmate ).show();
55+
}
56+
57+
public static final ImagePlus createLabelImagePlus( final TrackMate trackmate )
58+
{
59+
return createLabelImagePlus( trackmate.getModel(), trackmate.getSettings().imp );
60+
}
61+
62+
public static final ImagePlus createLabelImagePlus( final Model model, final ImagePlus imp )
63+
{
64+
final int[] dimensions = imp.getDimensions();
65+
final int[] dims = new int[] { dimensions[ 0 ], dimensions[ 1 ], dimensions[ 3 ], dimensions[ 4 ] };
66+
67+
final ImagePlus lblImp = createLabelImagePlus( model, dims );
68+
lblImp.setCalibration( imp.getCalibration().copy() );
69+
lblImp.setTitle( "LblImg_" + imp.getTitle() );
70+
return lblImp;
71+
}
72+
73+
/**
74+
* @param model
75+
* @param dimensions
76+
* the dimensions of the output image (width, height, nZSlices,
77+
* nFrames) as a 4 element int array.
78+
* @return a new {@link ImagePlus}
79+
*/
80+
81+
public static final ImagePlus createLabelImagePlus( final Model model, final int[] dimensions )
82+
{
83+
final long[] dims = new long[ 4 ];
84+
for ( int d = 0; d < dims.length; d++ )
85+
dims[ d ] = dimensions[ d ];
86+
87+
final ImagePlus lblImp = ImageJFunctions.wrap( createLabelImg( model, dims ), "LblImage" );
88+
lblImp.setDimensions( 1, dimensions[ 2 ], dimensions[ 3 ] );
89+
lblImp.setOpenAsHyperStack( true );
90+
return lblImp;
91+
}
92+
93+
/**
94+
* @param model
95+
* @param dimensions
96+
* the dimensions of the output image (width, height, nZSlices,
97+
* nFrames) as a 4 element int array.
98+
* @return a new {@link ImagePlus}
99+
*/
100+
101+
public static final Img< UnsignedShortType > createLabelImg( final Model model, final long[] dimensions )
102+
{
103+
/*
104+
* Create target image.
105+
*/
106+
final Dimensions targetSize = FinalDimensions.wrap( dimensions );
107+
final Img< UnsignedShortType > lblImg = Util.getArrayOrCellImgFactory( targetSize, new UnsignedShortType() ).create( targetSize );
108+
final AxisType[] axes = new AxisType[] {
109+
Axes.X,
110+
Axes.Y,
111+
Axes.Z,
112+
Axes.TIME };
113+
final ImgPlus< UnsignedShortType > imgPlus = new ImgPlus<>( lblImg, "LblImg", axes );
114+
115+
/*
116+
* Determine the starting id for spots not in tracks.
117+
*/
118+
119+
int maxTrackID = -1;
120+
final Set< Integer > trackIDs = model.getTrackModel().trackIDs( false );
121+
if ( null != trackIDs )
122+
for ( final Integer trackID : trackIDs )
123+
if ( trackID > maxTrackID )
124+
maxTrackID = trackID.intValue();
125+
final AtomicInteger lonelySpotID = new AtomicInteger( maxTrackID + 2 );
126+
127+
/*
128+
* Frame by frame iteration.
129+
*/
130+
131+
for ( int frame = 0; frame < dimensions[ 3 ]; frame++ )
132+
{
133+
final ImgPlus< UnsignedShortType > imgC = HyperSliceImgPlus.fixChannelAxis( imgPlus, 0 );
134+
final ImgPlus< UnsignedShortType > imgCT = HyperSliceImgPlus.fixTimeAxis( imgC, frame );
135+
for ( final Spot spot : model.getSpots().iterable( frame, true ) )
136+
{
137+
final int id;
138+
final Integer trackID = model.getTrackModel().trackIDOf( spot );
139+
if ( null == trackID || !model.getTrackModel().isVisible( trackID ) )
140+
id = lonelySpotID.getAndIncrement();
141+
else
142+
id = 1 + trackID.intValue();
143+
144+
final SpotNeighborhood< UnsignedShortType > neighborhood = new SpotNeighborhood< UnsignedShortType >( spot, imgCT );
145+
for ( final UnsignedShortType pixel : neighborhood )
146+
pixel.set( id );
147+
}
148+
}
149+
150+
return lblImg;
151+
}
152+
153+
@Plugin( type = TrackMateActionFactory.class )
154+
public static class Factory implements TrackMateActionFactory
155+
{
156+
157+
@Override
158+
public String getInfoText()
159+
{
160+
return INFO_TEXT;
161+
}
162+
163+
@Override
164+
public String getKey()
165+
{
166+
return KEY;
167+
}
168+
169+
@Override
170+
public TrackMateAction create( final TrackMateGUIController controller )
171+
{
172+
return new LabelImgExporter();
173+
}
174+
175+
@Override
176+
public ImageIcon getIcon()
177+
{
178+
return ICON;
179+
}
180+
181+
@Override
182+
public String getName()
183+
{
184+
return NAME;
185+
}
186+
}
187+
}
794 Bytes
Loading

0 commit comments

Comments
 (0)