3737import fiji .plugin .trackmate .Model ;
3838import fiji .plugin .trackmate .SelectionModel ;
3939import fiji .plugin .trackmate .Spot ;
40+ import fiji .plugin .trackmate .SpotCollection ;
4041import fiji .plugin .trackmate .TrackMate ;
4142import fiji .plugin .trackmate .TrackModel ;
4243import fiji .plugin .trackmate .gui .displaysettings .DisplaySettings ;
5253import net .imglib2 .RandomAccess ;
5354import net .imglib2 .img .Img ;
5455import net .imglib2 .img .display .imagej .ImageJFunctions ;
56+ import net .imglib2 .type .NativeType ;
5557import net .imglib2 .type .numeric .RealType ;
56- import net .imglib2 .type .numeric .integer .UnsignedShortType ;
5758import net .imglib2 .type .numeric .real .FloatType ;
5859import net .imglib2 .util .Util ;
5960import net .imglib2 .view .Views ;
@@ -121,8 +122,7 @@ public void execute( final TrackMate trackmate, final SelectionModel selectionMo
121122
122123 /**
123124 * Creates a new label {@link ImagePlus} where the spots of the specified
124- * model are painted as ellipsoids taken from their shape, with their track
125- * ID as pixel value.
125+ * model are painted with their shape, with their track ID as pixel value.
126126 *
127127 * @param trackmate
128128 * the trackmate instance from which we takes the spots to paint.
@@ -156,8 +156,7 @@ public static final ImagePlus createLabelImagePlus(
156156
157157 /**
158158 * Creates a new label {@link ImagePlus} where the spots of the specified
159- * model are painted as ellipsoids taken from their shape, with their track
160- * ID as pixel value.
159+ * model are painted with their shape, with their track ID as pixel value.
161160 *
162161 * @param trackmate
163162 * the trackmate instance from which we takes the spots to paint.
@@ -168,7 +167,7 @@ public static final ImagePlus createLabelImagePlus(
168167 * will be 1.
169168 * @param exportSpotsAsDots
170169 * if <code>true</code>, spots will be painted as single dots
171- * instead of ellipsoids .
170+ * instead their shape .
172171 * @param exportTracksOnly
173172 * if <code>true</code>, only the spots belonging to visible
174173 * tracks will be painted. If <code>false</code>, spots not
@@ -194,8 +193,7 @@ public static final ImagePlus createLabelImagePlus(
194193
195194 /**
196195 * Creates a new label {@link ImagePlus} where the spots of the specified
197- * model are painted as ellipsoids taken from their shape, with their track
198- * ID as pixel value.
196+ * model are painted with their shape, with their track ID as pixel value.
199197 *
200198 * @param model
201199 * the model from which we takes the spots to paint.
@@ -206,7 +204,7 @@ public static final ImagePlus createLabelImagePlus(
206204 * 1.
207205 * @param exportSpotsAsDots
208206 * if <code>true</code>, spots will be painted as single dots
209- * instead of ellipsoids .
207+ * instead their shape .
210208 * @param exportTracksOnly
211209 * if <code>true</code>, only the spots belonging to visible
212210 * tracks will be painted. If <code>false</code>, spots not
@@ -229,8 +227,7 @@ public static final ImagePlus createLabelImagePlus(
229227
230228 /**
231229 * Creates a new label {@link ImagePlus} where the spots of the specified
232- * model are painted as ellipsoids taken from their shape, with their track
233- * ID as pixel value.
230+ * model are painted with their shape, with their track ID as pixel value.
234231 *
235232 * @param model
236233 * the model from which we takes the spots to paint.
@@ -241,7 +238,7 @@ public static final ImagePlus createLabelImagePlus(
241238 * 1.
242239 * @param exportSpotsAsDots
243240 * if <code>true</code>, spots will be painted as single dots
244- * instead of ellipsoids .
241+ * instead their shape .
245242 * @param exportTracksOnly
246243 * if <code>true</code>, only the spots belonging to visible
247244 * tracks will be painted. If <code>false</code>, spots not
@@ -280,18 +277,17 @@ public static final ImagePlus createLabelImagePlus(
280277
281278 /**
282279 * Creates a new label {@link ImagePlus} where the spots of the specified
283- * model are painted as ellipsoids taken from their shape, with their track
284- * ID as pixel value.
280+ * model are painted with their shape, with their track ID as pixel value.
285281 *
286282 * @param model
287283 * the model from which we takes the spots to paint.
288284 * @param dimensions
289285 * the desired dimensions of the output image (width, height,
290- * nZSlices, nFrames) as a 4 element int array. Spots outside
286+ * nZSlices, nFrames) as a 4 element long array. Spots outside
291287 * these dimensions are ignored.
292288 * @param exportSpotsAsDots
293289 * if <code>true</code>, spots will be painted as single dots
294- * instead of ellipsoids .
290+ * instead their shape .
295291 * @param exportTracksOnly
296292 * if <code>true</code>, only the spots belonging to visible
297293 * tracks will be painted. If <code>false</code>, spots not
@@ -315,8 +311,7 @@ public static final ImagePlus createLabelImagePlus(
315311
316312 /**
317313 * Creates a new label {@link ImagePlus} where the spots of the specified
318- * model are painted as ellipsoids taken from their shape, with their track
319- * ID as pixel value.
314+ * model are painted with their shape, with their track ID as pixel value.
320315 *
321316 * @param model
322317 * the model from which we takes the spots to paint.
@@ -326,7 +321,7 @@ public static final ImagePlus createLabelImagePlus(
326321 * these dimensions are ignored.
327322 * @param exportSpotsAsDots
328323 * if <code>true</code>, spots will be painted as single dots
329- * instead of ellipsoids .
324+ * instead their shape .
330325 * @param exportTracksOnly
331326 * if <code>true</code>, only the spots belonging to visible
332327 * tracks will be painted. If <code>false</code>, spots not
@@ -362,19 +357,19 @@ public static final ImagePlus createLabelImagePlus(
362357 }
363358
364359 /**
365- * Creates a new label {@link Img} of {@link UnsignedShortType } where the
366- * spots of the specified model are painted as ellipsoids taken from their
367- * shape, with their track ID as pixel value.
360+ * Creates a new label {@link Img} of {@link FloatType } where the spots of
361+ * the specified model are painted with their shape, with their track ID as
362+ * pixel value.
368363 *
369364 * @param model
370365 * the model from which we takes the spots to paint.
371366 * @param dimensions
372367 * the desired dimensions of the output image (width, height,
373- * nZSlices, nFrames) as a 4 element int array. Spots outside
368+ * nZSlices, nFrames) as a 4 element long array. Spots outside
374369 * these dimensions are ignored.
375370 * @param exportSpotsAsDots
376371 * if <code>true</code>, spots will be painted as single dots
377- * instead of ellipsoids .
372+ * instead their shape .
378373 * @param exportTracksOnly
379374 * if <code>true</code>, only the spots belonging to visible
380375 * tracks will be painted. If <code>false</code>, spots not
@@ -397,19 +392,18 @@ public static final Img< FloatType > createLabelImg(
397392 }
398393
399394 /**
400- * Creates a new label {@link Img} of {@link UnsignedShortType} where the
401- * spots of the specified model are painted as ellipsoids taken from their
402- * shape, with their track ID as pixel value.
395+ * Creates a new label {@link Img} of {@link FloatType} where the spots of
396+ * the specified model are painted with their shape, with an ID pixel value.
403397 *
404398 * @param model
405399 * the model from which we takes the spots to paint.
406400 * @param dimensions
407401 * the desired dimensions of the output image (width, height,
408- * nZSlices, nFrames) as a 4 element int array. Spots outside
402+ * nZSlices, nFrames) as a 4 element long array. Spots outside
409403 * these dimensions are ignored.
410404 * @param exportSpotsAsDots
411405 * if <code>true</code>, spots will be painted as single dots
412- * instead of ellipsoids .
406+ * instead their shape .
413407 * @param exportTracksOnly
414408 * if <code>true</code>, only the spots belonging to visible
415409 * tracks will be painted. If <code>false</code>, spots not
@@ -475,6 +469,98 @@ public static final Img< FloatType > createLabelImg(
475469 return lblImg ;
476470 }
477471
472+
473+ /**
474+ * Creates a new label {@link ImgPlus} of {@link FloatType} where the spots
475+ * are painted with an ID. All visible spots are painted, whether they are
476+ * in a track or not.
477+ *
478+ * @param spots
479+ * the spots to paint.
480+ * @param dimensions
481+ * the desired dimensions of the output image (width, height,
482+ * nZSlices, nFrames) as a 4 element long array. Spots outside
483+ * these dimensions are ignored.
484+ * @param exportSpotsAsDots
485+ * if <code>true</code>, spots will be painted as single dots
486+ * instead of their shape.
487+ * @param labelIdPainting
488+ * specifies how to paint the label ID of spots. The
489+ * {@link LabelIdPainting#LABEL_IS_TRACK_ID} is not supported and
490+ * defaults to {@link LabelIdPainting#LABEL_IS_SPOT_ID}.
491+ * @param logger
492+ * a {@link Logger} instance, to report progress of the export
493+ * process.
494+ *
495+ * @return a new {@link ImgPlus}.
496+ */
497+ public static < T extends RealType < T > & NativeType < T > > ImgPlus < T > createLabelImg (
498+ final SpotCollection spots ,
499+ final long [] dimensions ,
500+ final double [] calibration ,
501+ final boolean exportSpotsAsDots ,
502+ final LabelIdPainting labelIdPainting ,
503+ final T outputType ,
504+ final Logger logger )
505+ {
506+ /*
507+ * Create target image.
508+ */
509+ final Dimensions targetSize = FinalDimensions .wrap ( dimensions );
510+ final Img < T > lblImg = Util .getArrayOrCellImgFactory ( targetSize , outputType ).create ( targetSize );
511+ final AxisType [] axes = new AxisType [] {
512+ Axes .X ,
513+ Axes .Y ,
514+ Axes .Z ,
515+ Axes .TIME };
516+ final ImgPlus < T > imgPlus = new ImgPlus <>( lblImg , "LblImg" , axes , calibration );
517+
518+ /*
519+ * How to assign an ID to spots.
520+ */
521+
522+ final IdGenerator idGenerator ;
523+ switch ( labelIdPainting )
524+ {
525+ case LABEL_IS_INDEX :
526+ idGenerator = new SpotIndexGeneratorUniqueInFrame ( null , false );
527+ break ;
528+ case LABEL_IS_INDEX_MOVIE_UNIQUE :
529+ idGenerator = new SpotIndexGeneratorUniqueInMovie ( null , false );
530+ break ;
531+ case LABEL_IS_SPOT_ID :
532+ case LABEL_IS_TRACK_ID :
533+ idGenerator = new SpotIdGenerator ( null , false );
534+ break ;
535+ default :
536+ throw new IllegalArgumentException ( "Unknown painting method: " + labelIdPainting );
537+ }
538+
539+ /*
540+ * Frame by frame iteration.
541+ */
542+
543+ logger .log ( "Writing label image.\n " );
544+ for ( int frame = 0 ; frame < dimensions [ 3 ]; frame ++ )
545+ {
546+ final ImgPlus < T > imgCT = TMUtils .hyperSlice ( imgPlus , 0 , frame );
547+ final SpotWriter spotWriter = exportSpotsAsDots
548+ ? new SpotAsDotWriter <>( imgCT )
549+ : new SpotRoiWriter <>( imgCT );
550+ idGenerator .nextFrame ();
551+
552+ for ( final Spot spot : spots .iterable ( frame , true ) )
553+ {
554+ final int id = idGenerator .id ( spot );
555+ spotWriter .write ( spot , id );
556+ }
557+ logger .setProgress ( ( double ) ( 1 + frame ) / dimensions [ 3 ] );
558+ }
559+ logger .log ( "Done.\n " );
560+
561+ return imgPlus ;
562+ }
563+
478564 @ Plugin ( type = TrackMateActionFactory .class )
479565 public static class Factory implements TrackMateActionFactory
480566 {
@@ -685,11 +771,14 @@ public SpotIdGenerator( final TrackModel tm, final boolean visibleTracksOnly )
685771 @ Override
686772 public int id ( final Spot spot )
687773 {
688- final Integer trackID = tm .trackIDOf ( spot );
689- if ( null == trackID || !tm .isVisible ( trackID ) )
774+ if ( tm != null )
690775 {
691- if ( visibleTracksOnly )
692- return -1 ;
776+ final Integer trackID = tm .trackIDOf ( spot );
777+ if ( null == trackID || !tm .isVisible ( trackID ) )
778+ {
779+ if ( visibleTracksOnly )
780+ return -1 ;
781+ }
693782 }
694783 return spot .ID () + 1 ;
695784 }
@@ -709,11 +798,14 @@ public SpotIndexGeneratorUniqueInMovie( final TrackModel tm, final boolean visib
709798 @ Override
710799 public int id ( final Spot spot )
711800 {
712- final Integer trackID = tm .trackIDOf ( spot );
713- if ( null == trackID || !tm .isVisible ( trackID ) )
801+ if ( tm != null )
714802 {
715- if ( visibleTracksOnly )
716- return -1 ;
803+ final Integer trackID = tm .trackIDOf ( spot );
804+ if ( null == trackID || !tm .isVisible ( trackID ) )
805+ {
806+ if ( visibleTracksOnly )
807+ return -1 ;
808+ }
717809 }
718810 return index .incrementAndGet ();
719811 }
0 commit comments