@Override
  public void map() {
    for (int d = 2; d < position.length; ++d) min[d] = max[d] = position[d];

    min[0] = target.min(0);
    min[1] = target.min(1);
    max[0] = target.max(0);
    max[1] = target.max(1);
    final FinalInterval sourceInterval = new FinalInterval(min, max);

    final long cr = -target.dimension(0);

    final RandomAccess<B> targetRandomAccess = target.randomAccess(target);
    final RandomAccess<A> sourceRandomAccess = source.randomAccess(sourceInterval);

    for (sourceRandomAccess.setPosition(min),
            targetRandomAccess.setPosition(min[0], 0),
            targetRandomAccess.setPosition(min[1], 1);
        targetRandomAccess.getLongPosition(1) <= max[1];
        sourceRandomAccess.move(cr, 0), targetRandomAccess.move(cr, 0), sourceRandomAccess.fwd(1),
            targetRandomAccess.fwd(1)) {
      for (;
          targetRandomAccess.getLongPosition(0) <= max[0];
          sourceRandomAccess.fwd(0), targetRandomAccess.fwd(0))
        converter.convert(sourceRandomAccess.get(), targetRandomAccess.get());
    }
  }
    @Override
    public void fwd() {

      if (--s[0] >= 0) source.fwd(0);
      else {
        int d = 1;
        for (; d < n; ++d) {
          if (--s[d] >= 0) {
            source.fwd(d);
            break;
          }
        }

        for (; d > 0; --d) {
          final int e = d - 1;
          final double rd = r[d];
          final long pd = s[d] - ri[d];

          final double rad = Math.sqrt(rd * rd - pd * pd);
          final long radi = (long) rad;
          r[e] = rad;
          ri[e] = radi;
          s[e] = 2 * radi;

          source.setPosition(position[e] - radi, e);
        }
      }
    }
  @Override
  public void fwd() {
    int d;
    for (d = 0; d < numDimensions; ++d) {
      if (--s[d] >= 0) {
        randomAccess.fwd(d);
        break;
      } else {
        s[d] = r[d] = 0;
        randomAccess.setPosition(center[d], d);
      }
    }

    if (d > 0) {
      final int e = d - 1;
      final long rd = r[d];
      final long pd = rd - s[d];

      final long rad = (long) (Math.sqrt(rd * rd - pd * pd));
      s[e] = 2 * rad;
      r[e] = rad;

      randomAccess.setPosition(center[e] - rad, e);
    }
  }
Example #4
0
  protected void integrateLineDim0(
      final Converter<R, T> converter,
      final RandomAccess<R> cursorIn,
      final RandomAccess<T> cursorOut,
      final T sum,
      final T tmpVar,
      final long size) {
    // compute the first pixel
    converter.convert(cursorIn.get(), sum);
    cursorOut.get().set(sum);

    for (long i = 2; i < size; ++i) {
      cursorIn.fwd(0);
      cursorOut.fwd(0);

      converter.convert(cursorIn.get(), tmpVar);
      sum.add(tmpVar);
      cursorOut.get().set(sum);
    }
  }
    public void fwd() {
      m_count++;

      if (m_count % m_breaks[0] == 0) {

        // we checked this already, so just do it
        m_ra.setPosition(0, 0);
        m_ra.fwd(1);

        // skip the last dim, is handled by previous
        // dims
        for (int i = 1; i < m_breaks.length - 1; i++) {
          if (m_count % m_breaks[i] == 0) {
            m_ra.setPosition(0, i);
            m_ra.fwd(i + 1);
          }
        }
      } else {
        m_ra.fwd(0);
      }
    }
Example #6
0
  protected void integrateLine(
      final int d, final RandomAccess<T> cursor, final T sum, final long size) {
    // init sum on first pixel that is not zero
    sum.set(cursor.get());

    for (long i = 2; i < size; ++i) {
      cursor.fwd(d);

      sum.add(cursor.get());
      cursor.get().set(sum);
    }
  }
Example #7
0
  /**
   * Computes the n-dimensional 1st derivative vector in 3x3x3...x3 environment for a certain {@link
   * Img} location defined by the position of the {@link LocalizableByDimCursor}.
   *
   * @param cursor - the position for which to compute the Hessian Matrix
   * @param derivativeVector - the derivative, which is essentially a one-dimensional {@link
   *     DoubleType} {@link Img} of size [numDimensions]
   */
  public static final <T extends RealType<T>> void computeDerivativeVector(
      final RandomAccess<T> cursor, final Img<DoubleType> derivativeVector) {
    // instantiate a cursor to traverse over the derivative vector we want to compute, the position
    // defines the current dimension
    final Cursor<DoubleType> derivativeCursor = derivativeVector.localizingCursor();

    while (derivativeCursor.hasNext()) {
      derivativeCursor.fwd();

      final int dim = derivativeCursor.getIntPosition(0);

      // we compute the derivative for dimension A like this
      //
      // | a0 | a1 | a2 |
      //        ^
      //        |
      //  Original position of Img cursor
      //
      // d(a) = (a2 - a0)/2
      // we divide by 2 because it is a jump over two pixels

      cursor.fwd(dim);

      final double a2 = cursor.get().getRealDouble();

      cursor.bck(dim);
      cursor.bck(dim);

      final double a0 = cursor.get().getRealDouble();

      // back to the original position
      cursor.fwd(dim);

      derivativeCursor.get().setReal((a2 - a0) / 2);
    }
  }
 /** Compute the inverse Hessian matrix from the the steepest descent images. */
 public static <T extends RealType<T>> double[][] computeInverseHessian(
     final RandomAccessibleInterval<T> descent) {
   final int n = descent.numDimensions() - 1;
   final int numParameters = (int) descent.dimension(n);
   final long[] dim = new long[n + 1];
   descent.dimensions(dim);
   dim[n] = 1;
   final LocalizingIntervalIterator pos = new LocalizingIntervalIterator(dim);
   final RandomAccess<T> r = descent.randomAccess();
   final double[] deriv = new double[numParameters];
   final double[][] H = new double[numParameters][numParameters];
   while (pos.hasNext()) {
     pos.fwd();
     r.setPosition(pos);
     for (int p = 0; p < numParameters; ++p) {
       deriv[p] = r.get().getRealDouble();
       r.fwd(n);
     }
     for (int i = 0; i < numParameters; ++i)
       for (int j = 0; j < numParameters; ++j) H[i][j] += deriv[i] * deriv[j];
   }
   return new Matrix(H).inverse().getArray();
 }
  // change the return type to Img<FloatType> and adjust the code accordingly
  public <T extends RealType<T>> Img<T> gradient(Img<T> img) {
    // create a new ImgLib2 image of same dimensions, but FloatType
    // to to that, create a new PlanarImgFactory and instantiate a new
    // Img<FloatType>
    /**
     * ImgFactory<T> imgFactory = img.factory(); Img<T> gradientImg = imgFactory.create( img,
     * img.firstElement() );
     */

    // create a localizing cursor on the GradientImg, it will iterate all pixels
    // and is able to efficiently return its position at each pixel, at each
    // pixel we will compute the gradient
    /** Cursor<T> cursor = gradientImg.localizingCursor(); */

    // We extend the input image by a mirroring out of bounds strategy so
    // that we can access pixels outside of the image
    RandomAccessible<T> view = Views.extendMirrorSingle(img);

    // instantiate a RandomAccess on the extended view, it will be used to
    // compute the gradient locally at each pixel location
    RandomAccess<T> randomAccess = view.randomAccess();

    // iterate over all pixels
    while (cursor.hasNext()) {
      // move the cursor to the next pixel
      cursor.fwd();

      // compute gradient in each dimension
      double gradient = 0;

      for (int d = 0; d < img.numDimensions(); ++d) {
        // set the randomaccess to the location of the cursor
        randomAccess.setPosition(cursor);

        // move one pixel back in dimension d
        randomAccess.bck(d);

        // get the value
        double v1 = randomAccess.get().getRealDouble();

        // move twice forward in dimension d, i.e.
        // one pixel above the location of the cursor
        randomAccess.fwd(d);
        randomAccess.fwd(d);

        // get the value
        double v2 = randomAccess.get().getRealDouble();

        // add the square of the magnitude of the gradient
        gradient += ((v2 - v1) * (v2 - v1)) / 4;
      }

      // the square root of all quadratic sums yields
      // the magnitude of the gradient at this location,
      // set the pixel value of the gradient image

      // change the value to float, otherwise it will not be
      // compatible
      cursor.get().setReal(Math.sqrt(gradient));
    }

    return gradientImg;
  }
  protected void convolve(
      final RandomAccess<T> inputIterator,
      final Cursor<T> outputIterator,
      final int dim,
      final float[] kernel,
      final long startPos,
      final long loopSize) {
    // move to the starting position of the current thread
    outputIterator.jumpFwd(startPos);

    final int filterSize = kernel.length;
    final int filterSizeMinus1 = filterSize - 1;
    final int filterSizeHalf = filterSize / 2;
    final int filterSizeHalfMinus1 = filterSizeHalf - 1;
    final int numDimensions = inputIterator.numDimensions();

    final int iteratorPosition = filterSizeHalf;

    final int[] to = new int[numDimensions];

    final T sum = inputIterator.get().createVariable();
    final T tmp = inputIterator.get().createVariable();

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

      // set the sum to zero
      sum.setZero();

      //
      // we move filtersize/2 of the convolved pixel in the input container
      //

      // get the current positon in the output container
      outputIterator.localize(to);

      // position in the input container is filtersize/2 to the left
      to[dim] -= iteratorPosition;

      // set the input cursor to this very position
      inputIterator.setPosition(to);

      // System.out.println( "out: " + outputIterator );
      // System.out.println( "iteratorPosition: " + iteratorPosition );
      // System.out.println( "in: " + inputIterator );
      // System.exit ( 0 );

      // iterate over the kernel length across the input container
      for (int f = -filterSizeHalf; f <= filterSizeHalfMinus1; ++f) {
        // get value from the input container
        tmp.set(inputIterator.get());

        // multiply the kernel
        tmp.mul(kernel[f + filterSizeHalf]);

        // add up the sum
        sum.add(tmp);

        // move the cursor forward for the next iteration
        inputIterator.fwd(dim);
      }

      //
      // for the last pixel we do not move forward
      //

      // get value from the input container
      tmp.set(inputIterator.get());

      // multiply the kernel
      tmp.mul(kernel[filterSizeMinus1]);

      // add up the sum
      sum.add(tmp);

      outputIterator.get().set(sum);
    }
  }
Example #11
0
  @Override
  public boolean process() {
    final int numDimensions = img.numDimensions();
    final long integralSize[] = new long[numDimensions];

    // the size of the first dimension is changed
    for (int d = 0; d < numDimensions; ++d) integralSize[d] = img.dimension(d) + 1;

    final Img<T> integral = imgFactory.create(integralSize, type);

    // not enough RAM or disc space
    if (integral == null) return false;

    this.integral = integral;

    if (numDimensions > 1) {
      final long[] fakeSize = new long[numDimensions - 1];

      // the size of dimension 0
      final long size = integralSize[0];

      for (int d = 1; d < numDimensions; ++d) fakeSize[d - 1] = integralSize[d];

      final long imageSize = getNumPixels(fakeSize);

      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() {
                  @Override
                  public void run() {
                    // Thread ID
                    final int myNumber = ai.getAndIncrement();

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

                    final LocalizingZeroMinIntervalIterator cursorDim =
                        new LocalizingZeroMinIntervalIterator(fakeSize);

                    // location for the input location
                    final long[] tmpIn = new long[numDimensions];

                    // location for the integral location
                    final long[] tmpOut = new long[numDimensions];

                    final long[] tmp = new long[numDimensions - 1];

                    final RandomAccess<R> cursorIn = img.randomAccess();
                    final RandomAccess<T> cursorOut = integral.randomAccess();

                    final T tmpVar = integral.firstElement().createVariable();
                    final T sum = integral.firstElement().createVariable();

                    cursorDim.jumpFwd(myChunk.getStartPosition());

                    // iterate over all dimensions except the one we are computing the integral in,
                    // which is dim=0 here
                    main:
                    for (long j = 0; j < loopSize; ++j) {
                      cursorDim.fwd();

                      // get all dimensions except the one we are currently doing the integral on
                      cursorDim.localize(tmp);

                      tmpIn[0] = 0;
                      tmpOut[0] = 1;

                      for (int d = 1; d < numDimensions; ++d) {
                        tmpIn[d] = tmp[d - 1] - 1;
                        tmpOut[d] = tmp[d - 1];

                        // all entries of position 0 are 0
                        if (tmpOut[d] == 0) continue main;
                      }

                      // set the cursor to the beginning of the correct line
                      cursorIn.setPosition(tmpIn);

                      // set the cursor in the integral image to the right position
                      cursorOut.setPosition(tmpOut);

                      // integrate over the line
                      integrateLineDim0(converter, cursorIn, cursorOut, sum, tmpVar, size);
                    }
                  }
                });

      SimpleMultiThreading.startAndJoin(threads);
    } else {
      final T tmpVar = integral.firstElement().createVariable();
      final T sum = integral.firstElement().createVariable();

      // the size of dimension 0
      final long size = integralSize[0];

      final RandomAccess<R> cursorIn = img.randomAccess();
      final RandomAccess<T> cursorOut = integral.randomAccess();

      cursorIn.setPosition(0, 0);
      cursorOut.setPosition(1, 0);

      // compute the first pixel
      converter.convert(cursorIn.get(), sum);
      cursorOut.get().set(sum);

      for (long i = 2; i < size; ++i) {
        cursorIn.fwd(0);
        cursorOut.fwd(0);

        converter.convert(cursorIn.get(), tmpVar);
        sum.add(tmpVar);
        cursorOut.get().set(sum);
      }

      return true;
    }

    for (int d = 1; d < numDimensions; ++d) {
      final int dim = d;

      final long[] fakeSize = new long[numDimensions - 1];

      // the size of dimension d
      final long size = integralSize[d];

      // get all dimensions except the one we are currently doing the integral on
      int countDim = 0;
      for (int e = 0; e < numDimensions; ++e) if (e != d) fakeSize[countDim++] = integralSize[e];

      final long imageSize = getNumPixels(fakeSize);

      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() {
                  @Override
                  public void run() {
                    // Thread ID
                    final int myNumber = ai.getAndIncrement();

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

                    final LocalizingZeroMinIntervalIterator cursorDim =
                        new LocalizingZeroMinIntervalIterator(fakeSize);

                    // local instances
                    final long[] tmp2 = new long[numDimensions - 1];
                    final long[] tmp = new long[numDimensions];

                    final RandomAccess<T> cursor = integral.randomAccess();
                    final T sum = integral.firstElement().createVariable();

                    cursorDim.jumpFwd(myChunk.getStartPosition());

                    for (long j = 0; j < loopSize; ++j) {
                      cursorDim.fwd();

                      // get all dimensions except the one we are currently doing the integral on
                      cursorDim.localize(tmp2);

                      tmp[dim] = 1;
                      int countDim = 0;
                      for (int e = 0; e < numDimensions; ++e)
                        if (e != dim) tmp[e] = tmp2[countDim++];

                      // update the cursor in the input image to the current dimension position
                      cursor.setPosition(tmp);

                      // sum up line
                      integrateLine(dim, cursor, sum, size);
                    }
                  }
                });

      SimpleMultiThreading.startAndJoin(threads);
    }

    return true;
  }
Example #12
0
  /**
   * Computes the n-dimensional Hessian Matrix in 3x3x3...x3 environment for a certain {@link Img}
   * location defined by the position of the {@link LocalizableByDimCursor}.
   *
   * @param cursor - the position for which to compute the Hessian Matrix
   * @param hessianMatrix - the hessian matrix, which is essentially a two-dimensional {@link
   *     DoubleType} {@link Img} of size [numDimensions][numDimensions]
   */
  public static final <T extends RealType<T>> void computeHessianMatrix(
      final RandomAccess<T> cursor, final Img<DoubleType> hessianMatrix) {
    // we need this for all diagonal elements
    final double temp = 2.0 * cursor.get().getRealDouble();

    // instantiate a cursor to traverse over the hessian matrix we want to compute, the position
    // defines the current dimensions
    final Cursor<DoubleType> hessianCursor = hessianMatrix.localizingCursor();

    // another cursor to fill the redundant lower area of the matrix
    final RandomAccess<DoubleType> hessianCursorLowerHalf = hessianMatrix.randomAccess();

    while (hessianCursor.hasNext()) {
      hessianCursor.fwd();

      final int dimA = hessianCursor.getIntPosition(0);
      final int dimB = hessianCursor.getIntPosition(1);

      if (dimA == dimB) {
        // diagonal elements h(aa) for dimension a
        // computed from the row a in the input Img
        //
        // | a0 | a1 | a2 |
        //        ^
        //        |
        //  Original position of Img cursor
        //
        // h(aa) = (a2-a1) - (a1-a0)
        //       = a2 - 2*a1 + a0

        cursor.fwd(dimA);

        final double a2 = cursor.get().getRealDouble();

        cursor.bck(dimA);
        cursor.bck(dimA);

        final double a0 = cursor.get().getRealDouble();

        // back to the original position
        cursor.fwd(dimA);

        hessianCursor.get().set(a2 - temp + a0);
      } else if (dimB
          > dimA) // we compute all elements above the diagonal (see below for explanation)
      {
        // other elements h(ab) are computed as a combination
        // of dimA (dimension a) and dimB (dimension b), i.e. we always operate in a
        // two-dimensional plane
        // ______________________
        // | a0b0 | a1b0 | a2b0 |
        // | a0b1 | a1b1 | a2b1 |
        // | a0b2 | a1b2 | a2b2 |
        // ----------------------
        // where a1b1 is the original position of the cursor
        //
        // h(ab) = ( (a2b2-a0b2)/2 - (a2b0 - a0b0)/2 )/2
        //
        // we divide by 2 because these are always jumps over two pixels

        // we only have to do that if dimB > dimA,
        // because h(ab) = h(ba)

        cursor.fwd(dimB);
        cursor.fwd(dimA);

        final double a2b2 = cursor.get().getRealDouble();

        cursor.bck(dimA);
        cursor.bck(dimA);

        final double a0b2 = cursor.get().getRealDouble();

        cursor.bck(dimB);
        cursor.bck(dimB);

        final double a0b0 = cursor.get().getRealDouble();

        cursor.fwd(dimA);
        cursor.fwd(dimA);

        final double a2b0 = cursor.get().getRealDouble();

        // back to the original position
        cursor.bck(dimA);
        cursor.fwd(dimB);

        hessianCursor.get().set(((a2b2 - a0b2) / 2 - (a2b0 - a0b0) / 2) / 2);

        // update the corresponding element below the diagonal
        hessianCursorLowerHalf.setPosition(dimB, 0);
        hessianCursorLowerHalf.setPosition(dimA, 1);

        hessianCursorLowerHalf.get().set(hessianCursor.get());
      }
    }
  }