protected Image<FloatType> getFloatImage() { if (floatImage == null) { ImageConverter<T, FloatType> convertToFloat = new ImageConverter<T, FloatType>( input, getFloatFactory(), new RealTypeConverter<T, FloatType>()); if (!convertToFloat.process()) return null; floatImage = convertToFloat.getResult(); } return floatImage; }
/** * Return a difference of gaussian image that measures the gradient at a scale defined by the two * sigmas of the gaussians. * * @param image * @param sigma1 * @param sigma2 * @return */ public Image<FloatType> getGradientImage() { /* * Create the DoG kernel. */ double[][] kernels1d1 = new double[input.getNumDimensions()][]; double[][] kernels1d2 = new double[input.getNumDimensions()][]; int[] kernelDimensions = input.createPositionArray(); int[] offset = input.createPositionArray(); for (int i = 0; i < kernels1d1.length; i++) { kernels1d1[i] = Util.createGaussianKernel1DDouble(sigma1[i], true); kernels1d2[i] = Util.createGaussianKernel1DDouble(sigma2[i], true); kernelDimensions[i] = kernels1d1[i].length; offset[i] = (kernels1d1[i].length - kernels1d2[i].length) / 2; } Image<FloatType> kernel = getFloatFactory().createImage(kernelDimensions); LocalizableCursor<FloatType> kc = kernel.createLocalizableCursor(); int[] position = input.createPositionArray(); for (FloatType t : kc) { kc.getPosition(position); double value1 = 1; double value2 = 1; for (int i = 0; i < kernels1d1.length; i++) { value1 *= kernels1d1[i][position[i]]; int position2 = position[i] - offset[i]; if ((position2 >= 0) && (position2 < kernels1d2[i].length)) { value2 *= kernels1d2[i][position2]; } else { value2 = 0; } } t.setReal(value1 - value2); } kc.close(); /* * Apply the kernel to the image. */ FourierConvolution<FloatType, FloatType> convolution = new FourierConvolution<FloatType, FloatType>(getFloatImage(), kernel); if (!convolution.process()) return null; Image<FloatType> result = convolution.getResult(); /* * Quantize the image. */ ComputeMinMax<FloatType> computeMinMax = new ComputeMinMax<FloatType>(result); computeMinMax.process(); final float min = computeMinMax.getMin().get(); final float max = computeMinMax.getMax().get(); if (max == min) return result; ImageConverter<FloatType, FloatType> quantizer = new ImageConverter<FloatType, FloatType>( result, result.getImageFactory(), new Converter<FloatType, FloatType>() { @Override public void convert(FloatType input, FloatType output) { float value = (input.get() - min) / (max - min); value = Math.round(value * 100); output.set(value); } }); quantizer.process(); return quantizer.getResult(); }
@Override public boolean process() { floatImage = null; if (output == null) { output = new Labeling<L>(labelingFactory, input.getDimensions(), null); } else { /* * Initialize the output to all background */ LocalizableCursor<LabelingType<L>> c = output.createLocalizableCursor(); List<L> background = c.getType().intern(new ArrayList<L>()); for (LabelingType<L> t : c) { t.setLabeling(background); } c.close(); } /* * Get the smoothed image. */ Image<FloatType> kernel = FourierConvolution.createGaussianKernel(input.getContainerFactory(), scale); FourierConvolution<FloatType, FloatType> convolution = new FourierConvolution<FloatType, FloatType>(getFloatImage(), kernel); if (!convolution.process()) return false; Image<FloatType> smoothed = convolution.getResult(); /* * Find the local maxima and label them individually. */ PickImagePeaks<FloatType> peakPicker = new PickImagePeaks<FloatType>(smoothed); peakPicker.setSuppression(scale); peakPicker.process(); Labeling<L> seeds = output.createNewLabeling(); LocalizableByDimCursor<LabelingType<L>> lc = seeds.createLocalizableByDimCursor(); LocalizableByDimCursor<FloatType> imageCursor = smoothed.createLocalizableByDimCursor(); int[] dimensions = input.getDimensions(); for (int[] peak : peakPicker.getPeakList()) { if (!filterPeak(imageCursor, peak, dimensions, false)) continue; lc.setPosition(peak); lc.getType().setLabel(names.next()); } imageCursor.close(); /* * Find the local minima and label them all the same. */ List<L> background = lc.getType().intern(names.next()); Converter<FloatType, FloatType> invert = new Converter<FloatType, FloatType>() { @Override public void convert(FloatType input, FloatType output) { output.setReal(-input.getRealFloat()); } }; ImageConverter<FloatType, FloatType> invSmoothed = new ImageConverter<FloatType, FloatType>(smoothed, smoothed, invert); invSmoothed.process(); peakPicker = new PickImagePeaks<FloatType>(smoothed); peakPicker.setSuppression(scale); peakPicker.process(); imageCursor = smoothed.createLocalizableByDimCursor(); for (int[] peak : peakPicker.getPeakList()) { if (!filterPeak(imageCursor, peak, dimensions, true)) continue; lc.setPosition(peak); lc.getType().setLabeling(background); } lc.close(); imageCursor.close(); smoothed = null; invSmoothed = null; Image<FloatType> gradientImage = getGradientImage(); if (gradientImage == null) return false; /* * Run the seeded watershed on the image. */ Watershed.seededWatershed(gradientImage, seeds, structuringElement, output); return true; }