
org.scijava.ops.image.create.Creators Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scijava-ops-image Show documentation
Show all versions of scijava-ops-image Show documentation
Image processing operations for SciJava Ops.
The newest version!
/*-
* #%L
* Image processing operations for SciJava Ops.
* %%
* Copyright (C) 2014 - 2024 SciJava developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* #L%
*/
package org.scijava.ops.image.create;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.function.BiFunction;
import java.util.function.Function;
import net.imglib2.Cursor;
import net.imglib2.Dimensions;
import net.imglib2.FinalDimensions;
import net.imglib2.Interval;
import net.imglib2.IterableInterval;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.img.Img;
import net.imglib2.img.ImgFactory;
import net.imglib2.img.array.ArrayImg;
import net.imglib2.img.array.ArrayImgFactory;
import net.imglib2.img.basictypeaccess.array.ArrayDataAccess;
import net.imglib2.roi.labeling.ImgLabeling;
import net.imglib2.roi.labeling.LabelingMapping;
import net.imglib2.type.BooleanType;
import net.imglib2.type.NativeType;
import net.imglib2.type.NativeTypeFactory;
import net.imglib2.type.Type;
import net.imglib2.type.logic.BitType;
import net.imglib2.type.numeric.ComplexType;
import net.imglib2.type.numeric.IntegerType;
import net.imglib2.type.numeric.complex.ComplexDoubleType;
import net.imglib2.type.numeric.complex.ComplexFloatType;
import net.imglib2.type.numeric.integer.ByteType;
import net.imglib2.type.numeric.integer.IntType;
import net.imglib2.type.numeric.integer.LongType;
import net.imglib2.type.numeric.integer.ShortType;
import net.imglib2.type.numeric.integer.UnsignedByteType;
import net.imglib2.type.numeric.integer.UnsignedIntType;
import net.imglib2.type.numeric.integer.UnsignedShortType;
import net.imglib2.type.numeric.real.DoubleType;
import net.imglib2.type.numeric.real.FloatType;
import net.imglib2.util.Util;
import net.imglib2.view.Views;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.scijava.function.Functions;
import org.scijava.function.Producer;
public class Creators, L, I extends IntegerType, T extends Type, C extends ComplexType, W extends ComplexType & NativeType, B extends BooleanType, A extends ArrayDataAccess> {
/* ImgFactories */
String iF = "imgFactory";
/**
* @output imgFactory
* @implNote op names='create.imgFactory, engine.create'
*/
public final Producer> factorySource =
() -> new ArrayImgFactory(new DoubleType());
// note that dims is not actually passed to the ImgFactory but instead is
// inspected to determine which will be returned.
/**
* @input dimensions
* @output imgFactory
* @implNote op names='create.imgFactory, engine.create'
*/
public final Function> factoryFromDims = (
dims) -> Util.getSuitableImgFactory(dims, new DoubleType());
/**
* @input dimensions
* @input type
* @output imgFactory
* @implNote op names='create.imgFactory, engine.create'
*/
public final BiFunction> factoryFromDimsAndType =
Util::getSuitableImgFactory;
/**
* @input img
* @output imgFactory
* @implNote op names='create.imgFactory, engine.create'
*/
public final Function
, ImgFactory> factoryFromImg = (img) -> img
.factory();
/* Imgs */
/**
* @input dimensions
* @input type
* @input factory
* @output img
* @implNote op names='create.img, engine.create'
*/
public final Functions.Arity3, Img> imgFromDimsTypeAndFactory =
(dims, type, factory) -> Imgs.create(factory, dims, type);
/**
* @input dimensions
* @input type
* @output img
* @implNote op names='create.img, engine.create'
*/
public final BiFunction> imgFromDimsAndType = (dims,
type) -> {
ImgFactory factory = dims instanceof Img> ? ((Img) dims).factory()
: Util.getSuitableImgFactory(dims, type);
return Imgs.create(factory, dims, type);
};
/**
* @input intArray
* @output img
* @implNote op names='create.img, engine.create'
*/
public final Function> imgFromIntArray = (array) -> {
FinalDimensions dims = new FinalDimensions(array);
DoubleType type = new DoubleType();
return Imgs.create(Util.getSuitableImgFactory(dims, type), dims, type);
};
/**
* @input integerArray
* @output img
* @implNote op names='create.img, engine.create'
*/
public final Function> imgFromIntegerArray = (
array) -> imgFromIntArray.apply(Arrays.stream(array).mapToInt(
Integer::intValue).toArray());
/**
* @input longArray
* @output img
* @implNote op names='create.img, engine.create'
*/
public final Function> imgFromPrimitiveLongArray = (
array) -> {
FinalDimensions dims = new FinalDimensions(array);
DoubleType type = new DoubleType();
return Imgs.create(Util.getSuitableImgFactory(dims, type), dims, type);
};
/**
* @input longArray
* @output img
* @implNote op names='create.img, engine.create'
*/
public final Function> imgFromLongArray = (
array) -> imgFromPrimitiveLongArray.apply(Arrays.stream(array).mapToLong(
Long::longValue).toArray());
/**
* @input ii
* @output img
* @implNote op names='create.img, engine.create', priority='0.'
*/
public final Function, Img> imgFromII = (
ii) -> imgFromDimsAndType.apply(ii, ii.firstElement());
/**
* @input inputImg
* @output img
* @implNote op names='create.img, engine.create', priority='100.'
*/
public final Function
, Img> imgFromImg = (img) -> Imgs.create(img
.factory(), img, img.firstElement());
/**
* @input interval
* @output img
* @implNote op names='create.img, engine.create', priority='-100.'
*/
public final Function> imgFromInterval = (
interval) -> {
DoubleType type = new DoubleType();
return Imgs.create(Util.getSuitableImgFactory(interval, type), interval,
type);
};
/**
* @input rai
* @output img
* @implNote op names='create.img, engine.create', priority='0.'
*/
public final Function, Img> imgFromRAI = (
rai) -> imgFromDimsAndType.apply(rai, Util.getTypeFromInterval(rai));
/**
* @input arrayImg
* @output img
* @implNote op names='create.img, engine.create', priority='1000.'
*/
@SuppressWarnings("unchecked")
public final Function, ArrayImg> arrayImgFromArrayImg //
= input -> (ArrayImg) input //
.factory() //
.create(input.dimensionsAsLongArray());
/* Type */
/**
* @input sampleType
* @output type
* @implNote op names='create.type, engine.create'
*/
public final Function typeFromSampleType = (sample) -> sample
.createVariable();
/* ImgLabeling */
/**
* @input img
* @output imgLabeling
* @implNote op names='create.imgLabeling, engine.create'
*/
public final Function
, ImgLabeling> imgLabelingFromImg =
ImgLabeling::new;
/**
* @input dimensions
* @input type
* @input factory
* @output imgLabeling
* @implNote op names='create.imgLabeling, engine.create'
*/
public final Functions.Arity3, ImgLabeling> imgLabelingFromDimsTypeAndFactory =
(dims, type, factory) -> {
Img img = Imgs.create(factory, dims, type);
return imgLabelingFromImg.apply(img);
};
/**
* @input dimensions
* @input type
* @output imgLabeling
* @implNote op names='create.imgLabeling, engine.create'
*/
public final BiFunction> imgLabelingFromDimsAndType =
(dims, type) -> imgLabelingFromDimsTypeAndFactory.apply(dims, type, Util
.getSuitableImgFactory(dims, type));
/* Kernel */
/**
* @input values
* @input type
* @output kernelRAI
* @implNote op names='create.kernel'
*/
public final BiFunction> kernel2DFromValuesAndType =
(arr, type) -> {
FinalDimensions dims = new FinalDimensions(new long[] { arr.length,
arr[0].length });
RandomAccessibleInterval rai =
(RandomAccessibleInterval) imgFromDimsAndType.apply(dims, (T) type);
Cursor cursor = Views.iterable(rai).cursor();
for (int j = 0; j < arr.length; j++) {
for (int k = 0; k < arr[j].length; k++) {
cursor.fwd();
cursor.get().setReal(arr[j][k]);
}
}
return rai;
};
// TODO do we want to support this and if so is this the right way to do it?
/**
* @input values
* @output kernelRAI
* @implNote op names='create.kernel'
*/
public final Function> kernel2DFromValues =
(arr) -> (RandomAccessibleInterval) kernel2DFromValuesAndType
.apply(arr, (C) new DoubleType());
/* Gaussian Kernel */
/**
* @input numDims
* @input type
* @output gaussKernelRAI
* @implNote op names='create.kernelGauss'
*/
public final BiFunction> kernelGauss =
(numDims, type) -> {
return DefaultCreateKernelGauss.createKernel(numDims, type,
imgFromDimsAndType);
};
/**
* @input sigmas
* @output gaussKernelRAI
* @implNote op names='create.kernelGauss'
*/
// TODO do we want to support this and if so is this the right way to do it?
public final Function> kernelGaussDoubleType =
(sigmas) -> (RandomAccessibleInterval) kernelGauss.apply(sigmas,
(C) new DoubleType());
/**
* @input sigma
* @input numDimensions
* @input outType
* @output gaussKernelRAI
* @implNote op names='create.kernelGauss'
*/
public final Functions.Arity3> kernelGaussSymmetric =
(sigma, numDims, type) -> {
double[] sigmas = new double[numDims];
Arrays.fill(sigmas, sigma);
return kernelGauss.apply(sigmas, type);
};
// TODO is this cast safe?
/**
* @input sigma
* @input numDimensions
* @output gaussKernelRAI
* @implNote op names='create.kernelGauss'
*/
public final BiFunction> kernelGaussSymmetricDoubleType =
(sigma,
numDims) -> (RandomAccessibleInterval) kernelGaussSymmetric
.apply(sigma, numDims, (C) new DoubleType());
/* Kernel Log */
/**
* @input sigmas
* @input outType
* @output logKernelRAI
* @implNote op names='create.kernelLog'
*/
public final BiFunction> kernelLog =
(sigmas, type) -> DefaultCreateKernelLog.createKernel(sigmas, type,
imgFromDimsAndType);
/**
* @input sigmas
* @output logKernelRAI
* @implNote op names='create.kernelLog'
*/
public final Function> kernelLogDoubleType =
(sigmas) -> (RandomAccessibleInterval) kernelLog.apply(sigmas,
(C) new DoubleType());
/**
* @input sigma
* @input numDimensions
* @input outType
* @output logKernelRAI
* @implNote op names='create.kernelLog'
*/
public final Functions.Arity3> kernelLogSymmetric =
(sigma, numDims, type) -> {
double[] sigmas = new double[numDims];
Arrays.fill(sigmas, sigma);
return kernelLog.apply(sigmas, type);
};
/**
* @input sigma
* @input numDimensions
* @output logKernelRAI
* @implNote op names='create.kernelLog'
*/
public final BiFunction> kernelLogSymmetricDoubleType =
(sigma,
numDims) -> (RandomAccessibleInterval) kernelLogSymmetric
.apply(sigma, numDims, (C) new DoubleType());
/* Kernel Diffraction */
/**
* @input dimensions
* @input NA
* @input lambda
* @input ns
* @input ni
* @input resLateral
* @input resAxial
* @input pZ
* @input type
* @output diffractionKernelRAI
* @implNote op names='create.kernelDiffraction'
*/
public final Functions.Arity9> kernelDiffraction =
(dims, NA, lambda, ns, ni, resLateral, resAxial, pZ,
type) -> DefaultCreateKernelGibsonLanni.createKernel(dims, NA, lambda, ns,
ni, resLateral, resAxial, pZ, type, imgFromDimsAndType);
/* Kernel BiGauss */
/**
* @input sigmas
* @input numDimensions
* @input outType
* @output biGaussKernelRAI
* @implNote op names='create.kernelBiGauss'
*/
public final Functions.Arity3> kernelBiGauss =
(sigmas, numDims, outType) -> DefaultCreateKernelBiGauss.createKernel(
sigmas, numDims, outType, imgFromDimsAndType);
/**
* @input sigmas
* @input numDimensions
* @output biGaussKernelRAI
* @implNote op names='create.kernelBiGauss'
*/
public final BiFunction> kernelBiGaussDoubleType =
(sigmas, numDims) -> (RandomAccessibleInterval) kernelBiGauss
.apply(sigmas, numDims, (C) new DoubleType());
/**
* @input sigmas
* @input numDims
* @input outType
* @output biGaussKernelRAI
* @implNote op names='create.kernel2ndDerivBiGauss'
*/
public final Functions.Arity3> kernel2ndDerivBiGauss =
(sigmas, numDims, outType) -> DefaultCreateKernel2ndDerivBiGauss
.createKernel(sigmas, numDims, outType, imgFromDimsAndType);
/**
* @input sigmas
* @input numDims
* @output biGaussKernelRAI
* @implNote op names='create.kernel2ndDerivBiGauss'
*/
public final BiFunction> kernel2ndDerivBiGaussDoubleType =
(sigmas,
numDims) -> (RandomAccessibleInterval) kernel2ndDerivBiGauss
.apply(sigmas, numDims, (C) new DoubleType());
/* Kernel Gabor */
/**
* @input sigmas
* @input periods
* @input outType
* @output gaborKernelRAI
* @implNote op names='create.kernelGabor'
*/
public final Functions.Arity3> kernelGabor =
(sigmas, periods, outType) -> DefaultCreateKernelGabor.createKernel(sigmas,
periods, outType, imgFromDimsAndType);
/**
* @input sigmas
* @input periods
* @output gaborKernelRAI
* @implNote op names='create.kernelGabor'
*/
public final BiFunction> kernelGaborDouble =
(sigmas, periods) -> (RandomAccessibleInterval) kernelGabor
.apply(sigmas, periods, (C) new DoubleType());
/**
* @input sigmas
* @input periods
* @output gaborKernelRAI
* @implNote op names='create.kernelGabor'
*/
public final BiFunction> kernelGaborFloat =
(sigmas, periods) -> (RandomAccessibleInterval) kernelGabor
.apply(sigmas, periods, (C) new FloatType());
/**
* @input sigmas
* @input periods
* @output gaborKernelRAI
* @implNote op names='create.kernelGabor'
*/
public final BiFunction> kernelGaborComplexDouble =
(sigmas,
periods) -> (RandomAccessibleInterval) kernelGabor
.apply(sigmas, periods, (C) new ComplexDoubleType());
/**
* @input sigmas
* @input periods
* @output gaborKernelRAI
* @implNote op names='create.kernelGabor'
*/
public final BiFunction> kernelGaborComplexFloat =
(sigmas,
periods) -> (RandomAccessibleInterval) kernelGabor
.apply(sigmas, periods, (C) new ComplexFloatType());
/**
* @input sigmas
* @input periods
* @input outType
* @output gaborKernelRAI
* @implNote op names='create.kernelGabor'
*/
public final Functions.Arity3> kernelGaborSingleSigma =
(sigma, periods, outType) -> {
double[] sigmas = new double[periods.length];
Arrays.fill(sigmas, sigma);
return DefaultCreateKernelGabor.createKernel(sigmas, periods, outType,
imgFromDimsAndType);
};
/**
* @input sigmas
* @input periods
* @output gaborKernelRAI
* @implNote op names='create.kernelGabor'
*/
public final BiFunction> kernelGaborDoubleSingleSigma =
(sigma, periods) -> {
double[] sigmas = new double[periods.length];
Arrays.fill(sigmas, sigma);
return (RandomAccessibleInterval) kernelGabor.apply(sigmas,
periods, (C) new DoubleType());
};
/**
* @input sigmas
* @input periods
* @output gaborKernelRAI
* @implNote op names='create.kernelGabor'
*/
public final BiFunction> kernelGaborFloatSingleSigma =
(sigma, periods) -> {
double[] sigmas = new double[periods.length];
Arrays.fill(sigmas, sigma);
return (RandomAccessibleInterval) kernelGabor.apply(sigmas,
periods, (C) new FloatType());
};
/**
* @input sigmas
* @input periods
* @output gaborKernelRAI
* @implNote op names='create.kernelGabor'
*/
public final BiFunction> kernelGaborComplexDoubleSingleSigma =
(sigma, periods) -> {
double[] sigmas = new double[periods.length];
Arrays.fill(sigmas, sigma);
return (RandomAccessibleInterval) kernelGabor.apply(
sigmas, periods, (C) new ComplexDoubleType());
};
/**
* @input sigmas
* @input periods
* @output gaborKernelRAI
* @implNote op names='create.kernelGabor'
*/
public final BiFunction> kernelGaborComplexFloatSingleSigma =
(sigma, periods) -> {
double[] sigmas = new double[periods.length];
Arrays.fill(sigmas, sigma);
return (RandomAccessibleInterval) kernelGabor.apply(
sigmas, periods, (C) new ComplexFloatType());
};
/* Kernel Sobel */
/**
* @input outType
* @output sobelKernelRAI
* @implNote op names='create.kernelSobel'
*/
public final Function> kernelSobel = (
outType) -> DefaultCreateKernelSobel.createKernel(outType,
imgFromDimsAndType);
/* Labeling Mapping */
// NOTE: We are returning an empty LabelingMapping, and because it is empty
// that
// L can be anything. So in this case it is safe to return an object with an
// unbounded type variable because the caller has to restrict it in the
// declaration.
/**
* @output labelingMapping
* @implNote op names='create.labelingMapping, engine.create'
*/
public final Producer> labelingMappingSource = //
() -> new LabelingMapping<>(new LongType());
public final Function integerTypeFromLong = (maxValue) -> {
if (maxValue <= 0L) return new IntType();
if (maxValue <= 1L) return new BitType();
if (maxValue <= 0x7fL) return new ByteType();
if (maxValue <= 0xffL) return new UnsignedByteType();
if (maxValue <= 0x7fffL) return new ShortType();
if (maxValue <= 0xffffL) return new UnsignedShortType();
if (maxValue <= 0x7fffffffL) return new IntType();
if (maxValue <= 0xffffffffL) return new UnsignedIntType();
return new LongType();
};
/**
* @input maxNumSets
* @output labelingMapping
* @implNote op names='create.labelingMapping'
*/
public final Function> labelingMapping = (
maxNumSets) -> new LabelingMapping<>(integerTypeFromLong.apply(maxNumSets
.longValue()));
/* Object */
/**
* @input class
* @output object
* @implNote op names='create.object, engine.create'
*/
public final Function, L> object = (clazz) -> {
try {
return clazz.getDeclaredConstructor().newInstance();
}
catch (final InstantiationException | IllegalAccessException
| InvocationTargetException | NoSuchMethodException e)
{
throw new IllegalArgumentException(e);
}
};
/**
* @output vector3d
* @implNote op names='create.vector, engine.create'
*/
public final Producer defaultVector3d = () -> new Vector3d();
/**
* @output vector3f
* @implNote op names='create.vector, engine.create'
*/
public final Producer defaultVector3f = () -> new Vector3f();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy