/*-
* #%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 java.util.ArrayList;
import mpicbg.spim.registration.ViewDataBeads;
public class Blending extends CombinedPixelWeightener<Blending>
{
final boolean useView[];
final int numViews;
final double[] weights;
final double[] minDistance;
final int[][] imageSizes;
protected Blending( final ArrayList<ViewDataBeads> views )
{
super( views );
numViews = views.size();
useView = new boolean[numViews];
weights = new double[numViews];
minDistance = new double[numViews];
// cache image sizes
imageSizes = new int[numViews][];
for ( int i = 0; i < numViews; ++i )
imageSizes[ i ] = views.get( i ).getImageSize();
}
@Override
public void updateWeights(final double[][] loc, final boolean[] useView)
{
// check which location are inside its respective view
int num = 0;
for (int view = 0; view < numViews; view++)
if (useView[view])
num++;
// compute the linear weights
computeLinearWeights(num, loc, useView);
}
@Override
public void updateWeights(final int[][] loc, final boolean[] useView)
{
// check which location are inside its respective view
int num = 0;
for (int view = 0; view < numViews; view++)
if (useView[view])
num++;
// compute the linear weights
computeLinearWeights(num, loc, useView);
}
@Override
public double getWeight(final int view) { return weights[view]; }
final private void computeLinearWeights( final int num, final int[][] loc, final boolean[] useView )
{
if (num <= 1)
{
for (int i = 0; i < useView.length; i++)
if (useView[i])
weights[i] = 1;
else
weights[i] = 0;
return;
}
// compute the minimal distance to the border for each image
double sumInverseWeights = 0;
for (int i = 0; i < useView.length; i++)
{
if (useView[i])
{
minDistance[i] = 1;
for (int dim = 0; dim < 3; dim++)
{
final int localImgPos = loc[i][dim];
double value = Math.min(localImgPos, imageSizes[ i ][ dim ] - localImgPos - 1) + 1;
final double imgHalf = imageSizes[ i ][ dim ]/2.0;
final double imgHalf10 = Math.round( 0.35 * imgHalf );
if ( value < imgHalf10 )
value = (value / imgHalf10);
else
value = 1;
minDistance[i] *= value;
}
// the distance to the image, so always +1
// minDistance[i]++;
if ( minDistance[i] < 0 )
minDistance[i] = 0;
else if ( minDistance[i] > 1)
minDistance[i] = 1;
weights[i] = Math.pow(minDistance[i], conf.alpha);
sumInverseWeights += weights[i];
}
}
if (sumInverseWeights == 0)
{
for (int i = 0; i < useView.length; i++)
weights[i] = 0;
}
else
{
// norm them so that the integral is 1
for (int i = 0; i < useView.length; i++)
if (useView[i])
weights[i] /= sumInverseWeights;
else
weights[i] = 0;
}
}
final private void computeLinearWeights( final int num, final double[][] loc, final boolean[] useView )
{
if (num <= 1)
{
for (int i = 0; i < useView.length; i++)
if (useView[i])
weights[i] = 1;
else
weights[i] = 0;
return;
}
// compute the minimal distance to the border for each image
double sumInverseWeights = 0;
for (int i = 0; i < useView.length; i++)
{
if (useView[i])
{
minDistance[i] = 1;
for (int dim = 0; dim < 3; dim++)
{
final double localImgPos = loc[i][dim];
double value = Math.min(localImgPos, imageSizes[ i ][ dim ] - localImgPos - 1) + 1;
final double imgHalf = imageSizes[ i ][ dim ]/2.0;
final double imgHalf10 = Math.round( 0.35 * imgHalf );
if ( value < imgHalf10 )
value = (value / imgHalf10);
else
value = 1;
minDistance[i] *= value;
}
// the distance to the image, so always +1
// minDistance[i]++;
if ( minDistance[i] < 0 )
minDistance[i] = 0;
else if ( minDistance[i] > 1)
minDistance[i] = 1;
weights[i] = Math.pow(minDistance[i], conf.alpha);
sumInverseWeights += weights[i];
}
}
if (sumInverseWeights == 0)
{
for (int i = 0; i < useView.length; i++)
weights[i] = 0;
}
else
{
// norm them so that the integral is 1
for (int i = 0; i < useView.length; i++)
if (useView[i])
weights[i] /= sumInverseWeights;
else
weights[i] = 0;
}
}
@Override
public void close()
{
//IOFunctions.println(new Date(System.currentTimeMillis()) + ": Finished Blending...");
}
}