Beispiel #1
0
 /**
  * Constructor
  *
  * @param image The intensity image to be labeled
  * @param scale the minimum distance between maxima of objects. Less technically, this should be
  *     the diameter of the smallest object.
  * @param sigma1 the standard deviation for the larger smoothing. The difference between sigma1
  *     and sigma2 should be roughly the width of the desired edge in the DoG image. A larger
  *     difference will obscure small, faint edges.
  * @param sigma2 the standard deviation for the smaller smoothing. This should be on the order of
  *     the largest insignificant feature in the image.
  * @param names - an iterator that generates names of type L for the labels. The iterator will
  *     waste the last name taken on the background label. You can use
  *     AllConnectedComponents.getIntegerNames() as your name generator if you don't care about
  *     names.
  */
 public GradientWatershed(
     Image<T> input, double[] scale, double[] sigma1, double[] sigma2, Iterator<L> names) {
   this.input = input;
   this.scale = scale;
   this.sigma1 = sigma1;
   this.sigma2 = sigma2;
   structuringElement = AllConnectedComponents.getStructuringElement(input.getNumDimensions());
   this.names = names;
   labelingFactory =
       new ImageFactory<LabelingType<L>>(new LabelingType<L>(), input.getContainerFactory());
 }
Beispiel #2
0
  /**
   * Return a difference of gaussian image that measures the gradient at a scale defined by the two
   * sigmas of the gaussians.
   *
   * @param image
   * @param sigma1
   * @param sigma2
   * @return
   */
  public Image<FloatType> getGradientImage() {
    /*
     * Create the DoG kernel.
     */
    double[][] kernels1d1 = new double[input.getNumDimensions()][];
    double[][] kernels1d2 = new double[input.getNumDimensions()][];
    int[] kernelDimensions = input.createPositionArray();
    int[] offset = input.createPositionArray();
    for (int i = 0; i < kernels1d1.length; i++) {
      kernels1d1[i] = Util.createGaussianKernel1DDouble(sigma1[i], true);
      kernels1d2[i] = Util.createGaussianKernel1DDouble(sigma2[i], true);
      kernelDimensions[i] = kernels1d1[i].length;
      offset[i] = (kernels1d1[i].length - kernels1d2[i].length) / 2;
    }
    Image<FloatType> kernel = getFloatFactory().createImage(kernelDimensions);
    LocalizableCursor<FloatType> kc = kernel.createLocalizableCursor();
    int[] position = input.createPositionArray();
    for (FloatType t : kc) {
      kc.getPosition(position);
      double value1 = 1;
      double value2 = 1;
      for (int i = 0; i < kernels1d1.length; i++) {
        value1 *= kernels1d1[i][position[i]];
        int position2 = position[i] - offset[i];
        if ((position2 >= 0) && (position2 < kernels1d2[i].length)) {
          value2 *= kernels1d2[i][position2];
        } else {
          value2 = 0;
        }
      }
      t.setReal(value1 - value2);
    }
    kc.close();
    /*
     * Apply the kernel to the image.
     */
    FourierConvolution<FloatType, FloatType> convolution =
        new FourierConvolution<FloatType, FloatType>(getFloatImage(), kernel);
    if (!convolution.process()) return null;
    Image<FloatType> result = convolution.getResult();
    /*
     * Quantize the image.
     */
    ComputeMinMax<FloatType> computeMinMax = new ComputeMinMax<FloatType>(result);
    computeMinMax.process();
    final float min = computeMinMax.getMin().get();
    final float max = computeMinMax.getMax().get();
    if (max == min) return result;

    ImageConverter<FloatType, FloatType> quantizer =
        new ImageConverter<FloatType, FloatType>(
            result,
            result.getImageFactory(),
            new Converter<FloatType, FloatType>() {

              @Override
              public void convert(FloatType input, FloatType output) {
                float value = (input.get() - min) / (max - min);
                value = Math.round(value * 100);
                output.set(value);
              }
            });
    quantizer.process();
    return quantizer.getResult();
  }
Beispiel #3
0
 protected boolean checkDimensions(double[] array) {
   return array.length == input.getNumDimensions();
 }
 @Override
 public int getNumDimensions() {
   return image.getNumDimensions();
 }
  /**
   * 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;
    }
    */
  }