public void bwd() {
      if (m_count % m_breaks[0] == 0) {

        // we check this already, so just do it
        m_ra.setPosition(m_lastPos[0], 0);
        m_ra.bck(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(m_lastPos[i], i);
            m_ra.bck(i + 1);
          }
        }
      } else {
        m_ra.bck(0);
      }

      m_count--;
    }
Example #2
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);
    }
  }
  // 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;
  }
Example #4
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());
      }
    }
  }