Пример #1
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);
    }
  }
Пример #2
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;
  }