/*- * #%L * Fiji distribution of ImageJ for the life sciences. * %% * Copyright (C) 2007 - 2017 Fiji developers. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-2.0.html>. * #L% */ package spim.process.interestpointdetection; import java.util.ArrayList; import java.util.Date; import java.util.List; import mpicbg.imglib.image.Image; import mpicbg.imglib.outofbounds.OutOfBoundsStrategyMirrorFactory; import mpicbg.imglib.type.numeric.real.FloatType; import mpicbg.spim.io.IOFunctions; import mpicbg.spim.registration.bead.laplace.LaPlaceFunctions; import mpicbg.spim.segmentation.SimplePeak; import net.imglib2.img.Img; import net.imglib2.util.Util; import spim.Threads; import spim.fiji.spimdata.interestpoints.InterestPoint; import spim.process.cuda.CUDADevice; import spim.process.cuda.CUDASeparableConvolution; import spim.process.fusion.FusionHelper; public class ProcessDOG { /** * @param deviceList - a list of CUDA capable devices (or null if classic CPU computation in Java) * @param accurateCUDA - use accurate CUDA implementation (including out of bounds or not) * @param img - ImgLib1 image * @param imglib2img - ImgLib2 image (based on same image data as the ImgLib1 image, must be a wrap) * @param sigma * @param threshold * @param localization * @param imageSigmaX * @param imageSigmaY * @param imageSigmaZ * @param findMin * @param findMax * @param minIntensity * @param maxIntensity * @return */ public static ArrayList< InterestPoint > compute( final CUDASeparableConvolution cuda, final List< CUDADevice > deviceList, final boolean accurateCUDA, final double percentGPUMem, final Image< FloatType > img, final Img< net.imglib2.type.numeric.real.FloatType > imglib2img, final float sigma, final float threshold, final int localization, final double imageSigmaX, final double imageSigmaY, final double imageSigmaZ, final boolean findMin, final boolean findMax, final double minIntensity, final double maxIntensity, final boolean keepIntensity ) { float initialSigma = sigma; final float minPeakValue = threshold; final float minInitialPeakValue; if ( localization == 0 ) minInitialPeakValue = minPeakValue; else minInitialPeakValue = threshold/10.0f; final float min, max; if ( Double.isNaN( minIntensity ) || Double.isNaN( maxIntensity ) || Double.isInfinite( minIntensity ) || Double.isInfinite( maxIntensity ) || minIntensity == maxIntensity ) { final float[] minmax = FusionHelper.minMax( imglib2img ); min = minmax[ 0 ]; max = minmax[ 1 ]; } else { min = (float)minIntensity; max = (float)maxIntensity; } IOFunctions.println( "(" + new Date(System.currentTimeMillis()) + "): min intensity = " + min + ", max intensity = " + max ); // normalize image FusionHelper.normalizeImage( imglib2img, min, max ); final float k = LaPlaceFunctions.computeK( 4 ); final float K_MIN1_INV = LaPlaceFunctions.computeKWeight(k); final int steps = 3; // // Compute the Sigmas for the gaussian convolution // final float[] sigmaStepsX = LaPlaceFunctions.computeSigma( steps, k, initialSigma ); final float[] sigmaStepsDiffX = LaPlaceFunctions.computeSigmaDiff( sigmaStepsX, (float)imageSigmaX ); final float[] sigmaStepsY = LaPlaceFunctions.computeSigma( steps, k, initialSigma ); final float[] sigmaStepsDiffY = LaPlaceFunctions.computeSigmaDiff( sigmaStepsY, (float)imageSigmaY ); final float[] sigmaStepsZ = LaPlaceFunctions.computeSigma( steps, k, initialSigma ); final float[] sigmaStepsDiffZ = LaPlaceFunctions.computeSigmaDiff( sigmaStepsZ, (float)imageSigmaZ ); final double[] sigma1 = new double[]{ sigmaStepsDiffX[0], sigmaStepsDiffY[0], sigmaStepsDiffZ[0] }; final double[] sigma2 = new double[]{ sigmaStepsDiffX[1], sigmaStepsDiffY[1], sigmaStepsDiffZ[1] }; // compute difference of gaussian DifferenceOfGaussianNewPeakFinder dog; if ( deviceList == null ) dog = new DifferenceOfGaussianNewPeakFinder( img, new OutOfBoundsStrategyMirrorFactory<FloatType>(), sigma1, sigma2, minInitialPeakValue, K_MIN1_INV ); else dog = new DifferenceOfGaussianCUDA( cuda, percentGPUMem, deviceList, img, imglib2img, accurateCUDA, sigma1, sigma2, minInitialPeakValue, K_MIN1_INV ); dog.setComputeConvolutionsParalell( false ); dog.setNumThreads( Threads.numThreads() ); // do quadratic fit?? if ( localization == 1 ) dog.setKeepDoGImage( true ); else dog.setKeepDoGImage( false ); IOFunctions.println( "(" + new Date(System.currentTimeMillis()) + "): computing difference-of-gausian (sigma=" + initialSigma + ", " + "threshold=" + minPeakValue + ", sigma1=" + Util.printCoordinates( sigma1 ) + ", sigma2=" + Util.printCoordinates( sigma2 ) + ")" ); if ( deviceList == null ) IOFunctions.println( new Date( System.currentTimeMillis() ) + ": Computing DoG image (CPU)." ); else IOFunctions.println( new Date( System.currentTimeMillis() ) + ": Computing DoG image (GPU)." ); dog.process(); final ArrayList< SimplePeak > peaks = dog.getSimplePeaks(); /* final ArrayList< SimplePeak > peaks = new ArrayList< SimplePeak >(); final ArrayList< DifferenceOfGaussianPeak<FloatType> > peakListOld = dog.getPeaks(); final int n = img.getNumDimensions(); for ( final DifferenceOfGaussianPeak<FloatType> peak : peakListOld ) { if ( peak.isValid() ) { final int[] location = new int[ n ]; for ( int d = 0; d < n; ++d ) location[ d ] = peak.getPosition( d ); peaks.add( new SimplePeak( location, peak.getValue().get(), peak.isMin(), peak.isMax() ) ); } } */ final ArrayList< InterestPoint > finalPeaks; if ( localization == 0 ) { finalPeaks = Localization.noLocalization( peaks, findMin, findMax, keepIntensity ); } else if ( localization == 1 ) { finalPeaks = Localization.computeQuadraticLocalization( peaks, dog.getDoGImage(), findMin, findMax, minPeakValue, keepIntensity ); dog.getDoGImage().close(); } else { finalPeaks = Localization.computeGaussLocalization( peaks, null, sigma, findMin, findMax, minPeakValue, keepIntensity ); } IOFunctions.println("(" + new Date(System.currentTimeMillis()) + "): Found " + finalPeaks.size() + " peaks." ); // explicitly call the garbage collection as there are some outofmemory issues when processing many timepoints dog = null; System.gc(); return finalPeaks; } }