Example #1
0
  @Override
  public boolean process() {
    final long startTime = System.currentTimeMillis();

    final long imageSize = image.getNumPixels();

    final AtomicInteger ai = new AtomicInteger(0);
    final Thread[] threads = SimpleMultiThreading.newThreads(getNumThreads());

    final Vector<Chunk> threadChunks = SimpleMultiThreading.divideIntoChunks(imageSize, numThreads);

    final boolean isCompatible =
        image.getContainer().compareStorageContainerCompatibility(output.getContainer());

    for (int ithread = 0; ithread < threads.length; ++ithread)
      threads[ithread] =
          new Thread(
              new Runnable() {
                public void run() {
                  // Thread ID
                  final int myNumber = ai.getAndIncrement();

                  // get chunk of pixels to process
                  final Chunk myChunk = threadChunks.get(myNumber);

                  // check if all container types are comparable so that we can use simple iterators
                  // we assume transivity here
                  if (isCompatible) {
                    // we can simply use iterators
                    computeSimple(myChunk.getStartPosition(), myChunk.getLoopSize());
                  } else {
                    // we need a combination of Localizable and LocalizableByDim
                    computeAdvanced(myChunk.getStartPosition(), myChunk.getLoopSize());
                  }
                }
              });

    SimpleMultiThreading.startAndJoin(threads);

    processingTime = System.currentTimeMillis() - startTime;

    return true;
  }
  /**
   * Can be called with values[ 3 ], i.e. [initialsigma, sigma2, threshold] or values[ 2 ], i.e.
   * [initialsigma, threshold]
   *
   * <p>The results are stored in the same array. If called with values[ 2 ], sigma2 changing will
   * be disabled
   *
   * @param text - the text which is shown when asking for the file
   * @param values - the initial values and also contains the result
   * @param sigmaMax - the maximal sigma allowed by the interactive app
   * @return {@link InteractiveDoG} - the instance for querying additional parameters
   */
  public static InteractiveDoG getInteractiveDoGParameters(
      final ImagePlus imp, final int channel, final double values[], final float sigmaMax) {
    if (imp.isDisplayedHyperStack())
      imp.setPosition(imp.getStackIndex(channel + 1, imp.getNSlices() / 2 + 1, 1));
    else imp.setSlice(imp.getStackIndex(channel + 1, imp.getNSlices() / 2 + 1, 1));

    imp.setRoi(0, 0, imp.getWidth() / 3, imp.getHeight() / 3);

    final InteractiveDoG idog = new InteractiveDoG(imp, channel);
    idog.setSigmaMax(sigmaMax);
    idog.setLookForMaxima(defaultInteractiveMaxima);
    idog.setLookForMinima(defaultInteractiveMinima);

    if (values.length == 2) {
      idog.setSigma2isAdjustable(false);
      idog.setInitialSigma((float) values[0]);
      idog.setThreshold((float) values[1]);
    } else {
      idog.setInitialSigma((float) values[0]);
      idog.setThreshold((float) values[2]);
    }

    idog.run(null);

    while (!idog.isFinished()) SimpleMultiThreading.threadWait(100);

    if (values.length == 2) {
      values[0] = idog.getInitialSigma();
      values[1] = idog.getThreshold();
    } else {
      values[0] = idog.getInitialSigma();
      values[1] = idog.getSigma2();
      values[2] = idog.getThreshold();
    }

    // remove the roi
    imp.killRoi();

    defaultInteractiveMaxima = idog.getLookForMaxima();
    defaultInteractiveMinima = idog.getLookForMinima();

    return idog;
  }
Example #3
0
  /**
   * Execute the segmentation part.
   *
   * <p>This method looks for bright blobs: bright object of approximately spherical shape, whose
   * expected diameter is given in argument. The method used for segmentation depends on the {@link
   * SpotSegmenter} chosen, and set in {@link #settings};
   *
   * <p>This gives us a collection of spots, which at this stage simply wrap a physical center
   * location. These spots are stored in a {@link SpotCollection} field, {@link #spots}, but
   * listeners of this model are <b>not</b> notified when the process is over.
   *
   * @see #getSpots()
   */
  public void execSegmentation() {
    final Settings settings = model.getSettings();
    final int segmentationChannel = settings.segmentationChannel;
    final Logger logger = model.getLogger();
    final ImagePlus imp = settings.imp;

    if (null == imp) {
      logger.error("No image to operate on.\n");
      return;
    }
    if (null == settings.segmenter) {
      logger.error("No segmenter selected.\n");
      return;
    }
    if (null == settings.segmenterSettings) {
      logger.error("No segmenter settings set.\n");
      return;
    }
    if (!settings
        .segmenterSettings
        .getClass()
        .equals(settings.segmenter.createDefaultSettings().getClass())) {
      logger.error(
          String.format(
              "Segmenter settings class does not match segmenter class: %s vs %s.\n",
              settings.segmenterSettings.getClass().getSimpleName(),
              settings.segmenter.createDefaultSettings().getClass().getSimpleName()));
      return;
    }

    final int numFrames = settings.tend - settings.tstart + 1;
    final SpotCollection spots = new SpotCollection();
    final AtomicInteger spotFound = new AtomicInteger(0);
    final AtomicInteger progress = new AtomicInteger(0);

    final Thread[] threads;
    if (useMultithreading) {
      threads = SimpleMultiThreading.newThreads();
    } else {
      threads = SimpleMultiThreading.newThreads(1);
    }

    // Prepare the thread array
    final AtomicInteger ai = new AtomicInteger(settings.tstart);
    for (int ithread = 0; ithread < threads.length; ithread++) {

      threads[ithread] =
          new Thread(
              "TrackMate spot feature calculating thread " + (1 + ithread) + "/" + threads.length) {

            public void run() {

              for (int i = ai.getAndIncrement(); i <= settings.tend; i = ai.getAndIncrement()) {

                Image<? extends RealType<?>> img =
                    TMUtils.getCroppedSingleFrameAsImage(
                        imp,
                        i,
                        segmentationChannel,
                        settings); // will be cropped according to settings
                List<Spot> s = execSingleFrameSegmentation(img, settings, i);

                // Add segmentation feature other than position
                for (Spot spot : s) {
                  spot.putFeature(Spot.POSITION_T, i * settings.dt);
                }
                spots.put(i, s);

                spotFound.addAndGet(s.size());
                logger.setProgress(progress.incrementAndGet() / (float) numFrames);
              } // Finished looping over frames
            }
          };
    }

    logger.setStatus("Segmenting...");
    logger.setProgress(0);

    SimpleMultiThreading.startAndJoin(threads);
    model.setSpots(spots, true);

    logger.log("Found " + spotFound.get() + " spots.\n");
    logger.setProgress(1);
    logger.setStatus("");
    return;
  }
  /**
   * Fuse one slice/volume (one channel)
   *
   * @param output - same the type of the ImagePlus input
   * @param input - FloatType, because of Interpolation that needs to be done
   * @param transform - the transformation
   */
  public static <T extends RealType<T>> void fuseChannel(
      final Image<T> output,
      final Image<FloatType> input,
      final float[] offset,
      final InvertibleCoordinateTransform transform,
      final InterpolatorFactory<FloatType> factory) {
    final int dims = output.getNumDimensions();
    long imageSize = output.getDimension(0);

    for (int d = 1; d < output.getNumDimensions(); ++d) imageSize *= output.getDimension(d);

    // run multithreaded
    final AtomicInteger ai = new AtomicInteger(0);
    final Thread[] threads = SimpleMultiThreading.newThreads();

    final Vector<Chunk> threadChunks =
        SimpleMultiThreading.divideIntoChunks(imageSize, threads.length);

    for (int ithread = 0; ithread < threads.length; ++ithread)
      threads[ithread] =
          new Thread(
              new Runnable() {
                public void run() {
                  // Thread ID
                  final int myNumber = ai.getAndIncrement();

                  // get chunk of pixels to process
                  final Chunk myChunk = threadChunks.get(myNumber);
                  final long startPos = myChunk.getStartPosition();
                  final long loopSize = myChunk.getLoopSize();

                  final LocalizableCursor<T> out = output.createLocalizableCursor();
                  final Interpolator<FloatType> in = input.createInterpolator(factory);

                  final float[] tmp = new float[input.getNumDimensions()];

                  try {
                    // move to the starting position of the current thread
                    out.fwd(startPos);

                    // do as many pixels as wanted by this thread
                    for (long j = 0; j < loopSize; ++j) {
                      out.fwd();

                      for (int d = 0; d < dims; ++d) tmp[d] = out.getPosition(d) + offset[d];

                      transform.applyInverseInPlace(tmp);

                      in.setPosition(tmp);
                      out.getType().setReal(in.getType().get());
                    }
                  } catch (NoninvertibleModelException e) {
                    IJ.log("Cannot invert model, qutting.");
                    return;
                  }
                }
              });

    SimpleMultiThreading.startAndJoin(threads);

    /*
    final LocalizableCursor<T> out = output.createLocalizableCursor();
    final Interpolator<FloatType> in = input.createInterpolator( factory );

    final float[] tmp = new float[ input.getNumDimensions() ];

    try
    {
    	while ( out.hasNext() )
    	{
    		out.fwd();

    		for ( int d = 0; d < dims; ++d )
    			tmp[ d ] = out.getPosition( d ) + offset[ d ];

    		transform.applyInverseInPlace( tmp );

    		in.setPosition( tmp );
    		out.getType().setReal( in.getType().get() );
    	}
    }
    catch (NoninvertibleModelException e)
    {
    	IJ.log( "Cannot invert model, qutting." );
    	return;
    }
    */
  }