/*- * #%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.interestpointregistration.centerofmass; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.Callable; import mpicbg.spim.io.IOFunctions; import mpicbg.spim.mpicbg.PointMatchGeneric; import net.imglib2.util.RealSum; import net.imglib2.util.Util; import spim.fiji.spimdata.interestpoints.InterestPoint; import spim.process.interestpointregistration.Detection; import spim.process.interestpointregistration.PairwiseMatch; public class CenterOfMassPairwise implements Callable< PairwiseMatch > { final PairwiseMatch pair; final String description; final int centerType; public CenterOfMassPairwise( final PairwiseMatch pair, final int centerType, final String description ) { this.pair = pair; this.centerType = centerType; this.description = description; } @Override public PairwiseMatch call() { if ( pair.getListA().size() < 1 || pair.getListB().size() < 1 ) { IOFunctions.println( "(" + new Date( System.currentTimeMillis() ) + "): " + description + ": " + "Not enough detections to match (1 required per list, |listA|= " + pair.getListA().size() + ", |listB|= " + pair.getListB().size() + ")" ); pair.setCandidates( new ArrayList< PointMatchGeneric< Detection > >() ); pair.setInliers( new ArrayList< PointMatchGeneric< Detection > >(), Double.NaN ); return pair; } final double[] centerA, centerB; if ( centerType == 0 ) { centerA = average( pair.getListA() ); centerB = average( pair.getListB() ); } else { centerA = median( pair.getListA() ); centerB = median( pair.getListB() ); } final ArrayList< PointMatchGeneric< Detection > > inliers = new ArrayList< PointMatchGeneric< Detection > >(); inliers.add( new PointMatchGeneric< Detection >( new Detection( 0, centerA ), new Detection( 0, centerB ) ) ); pair.setCandidates( inliers ); pair.setInliers( inliers, 0 ); IOFunctions.println( "(" + new Date( System.currentTimeMillis() ) + "): " + description + ": Center A: " + Util.printCoordinates( centerA ) + "Center B: " + Util.printCoordinates( centerB ) ); return pair; } private static final double[] average( final List< InterestPoint > list ) { final int n = list.get( 0 ).getL().length; final RealSum[] sum = new RealSum[ n ]; for ( int d = 0; d < n; ++d ) sum[ d ] = new RealSum(); for ( final InterestPoint i : list ) { final double[] l = i.getL(); for ( int d = 0; d < n; ++d ) sum[ d ].add( l[ d ] ); } final double[] center = new double[ n ]; for ( int d = 0; d < n; ++d ) center[ d ] = sum[ d ].getSum() / (double)list.size(); return center; } private static final double[] median( final List< InterestPoint > list ) { final int n = list.get( 0 ).getL().length; final double[][] values = new double[ n ][ list.size() ]; for ( int j = 0; j < list.size(); ++j ) { final double[] l = list.get( j ).getL(); for ( int d = 0; d < n; ++d ) values[ d ][ j ] = l[ d ]; } final double[] center = new double[ n ]; for ( int d = 0; d < n; ++d ) center[ d ] = Util.median( values[ d ] ); return center; } }