/*- * #%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.concurrent.atomic.AtomicInteger; import mpicbg.imglib.algorithm.OutputAlgorithm; import mpicbg.imglib.algorithm.math.ImageCalculatorInPlace; import mpicbg.imglib.algorithm.scalespace.DifferenceOfGaussianPeak; import mpicbg.imglib.algorithm.scalespace.DifferenceOfGaussianReal1; import mpicbg.imglib.function.Function; import mpicbg.imglib.image.Image; import mpicbg.imglib.multithreading.SimpleMultiThreading; import mpicbg.imglib.outofbounds.OutOfBoundsStrategyFactory; import mpicbg.imglib.type.numeric.real.FloatType; import mpicbg.spim.io.IOFunctions; import mpicbg.spim.segmentation.InteractiveIntegral; import mpicbg.spim.segmentation.SimplePeak; public class DifferenceOfGaussianNewPeakFinder extends DifferenceOfGaussianReal1< FloatType > { ArrayList< SimplePeak > simplePeaks; final double min; // TODO: Remove this once the bug fix is uploaded final double[] s1, s2; public DifferenceOfGaussianNewPeakFinder( final Image< FloatType> img, OutOfBoundsStrategyFactory< FloatType> outOfBoundsFactory, final double[] sigma1, final double[] sigma2, double minPeakValue, double normalizationFactor) { super( img, outOfBoundsFactory, sigma1, sigma2, minPeakValue, normalizationFactor ); this.s1 = sigma1; this.s2 = sigma2; this.min = minPeakValue; } public ArrayList< SimplePeak > getSimplePeaks() { return simplePeaks; } @Override public ArrayList<DifferenceOfGaussianPeak< FloatType>> findPeaks( final Image< FloatType > laPlace ) { IOFunctions.println( new Date( System.currentTimeMillis() ) + ": Detecting peaks." ); simplePeaks = InteractiveIntegral.findPeaks( laPlace, (float)min ); return new ArrayList<DifferenceOfGaussianPeak< FloatType>>(); } // TODO: This is fixed in Imglib1 itself, remove once this is uploaded! /** * Has to be overwritten as the ImageCalculator does not do the right amount of threads */ @Override public boolean process() { // // perform the gaussian convolutions transferring it to the new (potentially higher precision) type T // final int divisor = getComputeConvolutionsParalell() ? 2 : 1; final OutputAlgorithm<FloatType> conv1 = getGaussianConvolution( s1, Math.max( 1, getNumThreads() / divisor ) ); final OutputAlgorithm<FloatType> conv2 = getGaussianConvolution( s2, Math.max( 1, getNumThreads() / divisor ) ); final Image<FloatType> gauss1, gauss2; if ( conv1.checkInput() && conv2.checkInput() ) { final AtomicInteger ai = new AtomicInteger(0); Thread[] threads = SimpleMultiThreading.newThreads( divisor ); for (int ithread = 0; ithread < threads.length; ++ithread) threads[ithread] = new Thread(new Runnable() { public void run() { final int myNumber = ai.getAndIncrement(); if ( myNumber == 0 || !getComputeConvolutionsParalell() ) { if ( !conv1.process() ) System.out.println( "Cannot compute gaussian convolution 1: " + conv1.getErrorMessage() ); } if ( myNumber == 1 || !getComputeConvolutionsParalell() ) { if ( !conv2.process() ) System.out.println( "Cannot compute gaussian convolution 2: " + conv2.getErrorMessage() ); } } }); SimpleMultiThreading.startAndJoin( threads ); } else { gauss1 = gauss2 = null; return false; } if ( conv1.getErrorMessage().length() == 0 && conv2.getErrorMessage().length() == 0 ) { gauss1 = conv1.getResult(); gauss2 = conv2.getResult(); } else { gauss1 = gauss2 = null; return false; } // // subtract the images to get the LaPlace image // final Function<FloatType, FloatType, FloatType> function = getNormalizedSubtraction(); final ImageCalculatorInPlace<FloatType, FloatType> imageCalc = new ImageCalculatorInPlace<FloatType, FloatType>( gauss2, gauss1, function ); imageCalc.setNumThreads( getNumThreads() ); if ( !imageCalc.checkInput() || !imageCalc.process() ) { gauss1.close(); gauss2.close(); return false; } gauss1.close(); peaks.clear(); peaks.addAll( findPeaks( gauss2 ) ); if ( getKeepDoGImage() ) dogImage = gauss2; else gauss2.close(); return true; } }