@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; }
/** * 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; } */ }