/*- * #%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 mpicbg.spim.fusion; import ij.IJ; import mpicbg.imglib.algorithm.fft.FourierConvolution; import mpicbg.imglib.container.ContainerFactory; import mpicbg.imglib.container.array.ArrayContainerFactory; import mpicbg.imglib.cursor.Cursor; import mpicbg.imglib.cursor.LocalizableByDimCursor; import mpicbg.imglib.image.Image; import mpicbg.imglib.outofbounds.OutOfBoundsStrategyFactory; import mpicbg.imglib.type.numeric.real.FloatType; import mpicbg.spim.io.SPIMConfiguration; import mpicbg.spim.registration.ViewDataBeads; public class GaussContent extends IsolatedPixelWeightener<GaussContent> { Image<FloatType> gaussContent; protected GaussContent( final ViewDataBeads view, final ContainerFactory entropyContainer ) { super( view ); try { final SPIMConfiguration conf = view.getViewStructure().getSPIMConfiguration(); // get the kernels final double[] k1 = new double[ view.getNumDimensions() ]; final double[] k2 = new double[ view.getNumDimensions() ]; for ( int d = 0; d < view.getNumDimensions() - 1; ++d ) { k1[ d ] = conf.fusionSigma1; k2[ d ] = conf.fusionSigma2; } k1[ view.getNumDimensions() - 1 ] = conf.fusionSigma1 / view.getZStretching(); k2[ view.getNumDimensions() - 1 ] = conf.fusionSigma2 / view.getZStretching(); final Image<FloatType> kernel1 = FourierConvolution.createGaussianKernel( new ArrayContainerFactory(), k1 ); final Image<FloatType> kernel2 = FourierConvolution.createGaussianKernel( new ArrayContainerFactory(), k2 ); // compute I*sigma1 FourierConvolution<FloatType, FloatType> fftConv1 = new FourierConvolution<FloatType, FloatType>( view.getImage(), kernel1 ); fftConv1.process(); final Image<FloatType> conv1 = fftConv1.getResult(); fftConv1.close(); fftConv1 = null; // compute ( I - I*sigma1 )^2 final Cursor<FloatType> cursorImg = view.getImage().createCursor(); final Cursor<FloatType> cursorConv = conv1.createCursor(); while ( cursorImg.hasNext() ) { cursorImg.fwd(); cursorConv.fwd(); final float diff = cursorImg.getType().get() - cursorConv.getType().get(); cursorConv.getType().set( diff*diff ); } // compute ( ( I - I*sigma1 )^2 ) * sigma2 FourierConvolution<FloatType, FloatType> fftConv2 = new FourierConvolution<FloatType, FloatType>( conv1, kernel2 ); fftConv2.process(); gaussContent = fftConv2.getResult(); fftConv2.close(); fftConv2 = null; // close the unnecessary image kernel1.close(); kernel2.close(); conv1.close(); ViewDataBeads.normalizeImage( gaussContent ); } catch ( OutOfMemoryError e ) { IJ.log( "OutOfMemory: Cannot compute Gauss approximated Entropy for " + view.getName() + ": " + e ); e.printStackTrace(); gaussContent = null; } } @Override public LocalizableByDimCursor<FloatType> getResultIterator() { // the iterator we need to get values from the weightening image return gaussContent.createLocalizableByDimCursor(); } @Override public LocalizableByDimCursor<FloatType> getResultIterator( OutOfBoundsStrategyFactory<FloatType> factory ) { // the iterator we need to get values from the weightening image return gaussContent.createLocalizableByDimCursor( factory ); } @Override public void close() { gaussContent.close(); } @Override public Image<FloatType> getResultImage() { return gaussContent; } }