Search in sources :

Example 1 with DetectionCreator

use of org.mastodon.tracking.detection.DetectionCreatorFactory.DetectionCreator in project mastodon-tracking by mastodon-sc.

the class LoGDetectorOp method mutate1.

@Override
public void mutate1(final DetectionCreatorFactory detectionCreatorFactory, final List<SourceAndConverter<?>> sources) {
    ok = false;
    final long start = System.currentTimeMillis();
    final StringBuilder str = new StringBuilder();
    if (!DetectionUtil.checkSettingsValidity(settings, str)) {
        processingTime = System.currentTimeMillis() - start;
        statusService.clearStatus();
        errorMessage = str.toString();
        return;
    }
    final int minTimepoint = (int) settings.get(KEY_MIN_TIMEPOINT);
    final int maxTimepoint = (int) settings.get(KEY_MAX_TIMEPOINT);
    final int setup = (int) settings.get(KEY_SETUP_ID);
    // um
    final double radius = (double) settings.get(KEY_RADIUS);
    final double threshold = (double) settings.get(KEY_THRESHOLD);
    final Interval roi = (Interval) settings.get(KEY_ROI);
    statusService.showStatus("LoG detection");
    for (int tp = minTimepoint; tp <= maxTimepoint; tp++) {
        statusService.showProgress(tp - minTimepoint + 1, maxTimepoint - minTimepoint + 1);
        // Did we get canceled?
        if (isCanceled())
            break;
        // Check if there is some data at this timepoint.
        if (!DetectionUtil.isPresent(sources, setup, tp))
            continue;
        /*
			 * Determine optimal level for detection.
			 */
        final int level = DetectionUtil.determineOptimalResolutionLevel(sources, radius, MIN_SPOT_PIXEL_SIZE / 2., tp, setup);
        /*
			 * Load and extends image data.
			 */
        @SuppressWarnings("rawtypes") final RandomAccessibleInterval img = DetectionUtil.getImage(sources, tp, setup, level);
        if (!DetectionUtil.isReallyPresent(img))
            continue;
        @SuppressWarnings("unchecked") final RandomAccessibleInterval<?> zeroMin = Views.dropSingletonDimensions(Views.zeroMin(img));
        /*
			 * Transform ROI in higher level.
			 */
        final Interval interval;
        if (null == roi) {
            interval = zeroMin;
        } else {
            final double[] minSource = new double[3];
            final double[] maxSource = new double[3];
            roi.realMin(minSource);
            roi.realMax(maxSource);
            final double[] minTarget = new double[3];
            final double[] maxTarget = new double[3];
            final AffineTransform3D mipmapTransform = DetectionUtil.getMipmapTransform(sources, tp, setup, level);
            mipmapTransform.applyInverse(minTarget, minSource);
            mipmapTransform.applyInverse(maxTarget, maxSource);
            final long[] tmin = new long[zeroMin.numDimensions()];
            final long[] tmax = new long[zeroMin.numDimensions()];
            for (int d = 0; d < zeroMin.numDimensions(); d++) {
                tmin[d] = (long) Math.ceil(minTarget[d]);
                tmax[d] = (long) Math.floor(maxTarget[d]);
            }
            final FinalInterval transformedRoi = new FinalInterval(tmin, tmax);
            interval = Intervals.intersect(transformedRoi, zeroMin);
        }
        /*
			 * Filter image.
			 */
        final double[] pixelSize = DetectionUtil.getPixelSize(sources, tp, setup, level);
        final RandomAccessibleInterval<FloatType> kernel = createLoGKernel(radius, zeroMin.numDimensions(), pixelSize);
        @SuppressWarnings("rawtypes") final IntervalView source = Views.interval(zeroMin, interval);
        @SuppressWarnings("unchecked") final RandomAccessibleInterval<FloatType> output = ops().filter().convolve(source, kernel);
        /*
			 * LoG normalization factor, so that the filtered peak have the
			 * maximal value for spots that have the size this kernel is tuned
			 * to. With this value, the peak value will be of the same order of
			 * magnitude than the raw spot (if it has the right size). This
			 * value also ensures that if the image has its calibration changed,
			 * one will retrieve the same peak value than before scaling.
			 * However, I (JYT) could not derive the exact formula if the image
			 * is scaled differently across X, Y and Z.
			 */
        final double sigma = radius / Math.sqrt(img.numDimensions());
        final double sigmaPixels = sigma / pixelSize[0];
        final FloatType C = new FloatType((float) (1. / Math.PI / sigmaPixels / sigmaPixels));
        Views.iterable(output).forEach((e) -> e.div(C));
        /*
			 * Detect local maxima.
			 */
        final AffineTransform3D transform = DetectionUtil.getTransform(sources, tp, setup, level);
        final DetectionCreator detectionCreator = detectionCreatorFactory.create(tp);
        final List<Point> peaks = DetectionUtil.findLocalMaxima(output, threshold, threadService.getExecutorService());
        if (doSubpixelLocalization) {
            final int maxNumMoves = 10;
            final boolean allowMaximaTolerance = true;
            final boolean returnInvalidPeaks = true;
            final boolean[] allowedToMoveInDim = new boolean[img.numDimensions()];
            Arrays.fill(allowedToMoveInDim, true);
            final float maximaTolerance = 0.01f;
            final List<RefinedPeak<Point>> refined = SubpixelLocalization.refinePeaks(peaks, output, output, returnInvalidPeaks, maxNumMoves, allowMaximaTolerance, maximaTolerance, allowedToMoveInDim);
            final RandomAccess<FloatType> ra = output.randomAccess();
            final double[] pos = new double[3];
            final RealPoint point = RealPoint.wrap(pos);
            final RealPoint p3d = new RealPoint(3);
            detectionCreator.preAddition();
            try {
                for (final RefinedPeak<Point> refinedPeak : refined) {
                    ra.setPosition(refinedPeak.getOriginalPeak());
                    final double q = ra.get().getRealDouble();
                    for (int d = 0; d < refinedPeak.numDimensions(); d++) p3d.setPosition(refinedPeak.getDoublePosition(d), d);
                    transform.apply(p3d, point);
                    detectionCreator.createDetection(pos, radius, q);
                }
            } finally {
                detectionCreator.postAddition();
            }
        } else {
            final RandomAccess<FloatType> ra = output.randomAccess();
            final double[] pos = new double[3];
            final RealPoint point = RealPoint.wrap(pos);
            detectionCreator.preAddition();
            try {
                for (final Point peak : peaks) {
                    ra.setPosition(peak);
                    final double q = ra.get().getRealDouble();
                    transform.apply(peak, point);
                    detectionCreator.createDetection(pos, radius, q);
                }
            } finally {
                detectionCreator.postAddition();
            }
        }
    }
    final long end = System.currentTimeMillis();
    processingTime = end - start;
    statusService.clearStatus();
    ok = true;
}
Also used : FloatType(net.imglib2.type.numeric.real.FloatType) IntervalView(net.imglib2.view.IntervalView) RealPoint(net.imglib2.RealPoint) AffineTransform3D(net.imglib2.realtransform.AffineTransform3D) Point(net.imglib2.Point) RealPoint(net.imglib2.RealPoint) Point(net.imglib2.Point) RealPoint(net.imglib2.RealPoint) DetectionCreator(org.mastodon.tracking.detection.DetectionCreatorFactory.DetectionCreator) RandomAccessibleInterval(net.imglib2.RandomAccessibleInterval) FinalInterval(net.imglib2.FinalInterval) RefinedPeak(net.imglib2.algorithm.localextrema.RefinedPeak) RandomAccessibleInterval(net.imglib2.RandomAccessibleInterval) FinalInterval(net.imglib2.FinalInterval) Interval(net.imglib2.Interval)

Example 2 with DetectionCreator

use of org.mastodon.tracking.detection.DetectionCreatorFactory.DetectionCreator in project mastodon-tracking by mastodon-sc.

the class DoGDetectorOp method mutate1.

@Override
public void mutate1(final DetectionCreatorFactory detectionCreatorFactory, final List<SourceAndConverter<?>> sources) {
    ok = false;
    final long start = System.currentTimeMillis();
    final StringBuilder str = new StringBuilder();
    if (!DetectionUtil.checkSettingsValidity(settings, str)) {
        processingTime = System.currentTimeMillis() - start;
        statusService.clearStatus();
        errorMessage = str.toString();
        return;
    }
    final int minTimepoint = (int) settings.get(KEY_MIN_TIMEPOINT);
    final int maxTimepoint = (int) settings.get(KEY_MAX_TIMEPOINT);
    final int setup = (int) settings.get(KEY_SETUP_ID);
    final double radius = (double) settings.get(KEY_RADIUS);
    final double threshold = (double) settings.get(KEY_THRESHOLD);
    final Interval roi = (Interval) settings.get(KEY_ROI);
    final DetectionType detectionType = DetectionType.getOrDefault((String) settings.get(KEY_DETECTION_TYPE), DetectionType.MINIMA);
    statusService.showStatus("DoG detection.");
    for (int tp = minTimepoint; tp <= maxTimepoint; tp++) {
        statusService.showProgress(tp - minTimepoint + 1, maxTimepoint - minTimepoint + 1);
        // Did we get canceled?
        if (isCanceled())
            break;
        // Check if there is some data at this timepoint.
        if (!DetectionUtil.isPresent(sources, setup, tp))
            continue;
        /*
			 * Determine optimal level for detection.
			 */
        final int level = DetectionUtil.determineOptimalResolutionLevel(sources, radius, MIN_SPOT_PIXEL_SIZE / 2., tp, setup);
        /*
			 * Load and extends image data.
			 */
        final RandomAccessibleInterval<?> img = DetectionUtil.getImage(sources, tp, setup, level);
        if (!DetectionUtil.isReallyPresent(img))
            continue;
        // If 2D, the 3rd dimension will be dropped here.
        final RandomAccessibleInterval<?> zeroMin = Views.dropSingletonDimensions(Views.zeroMin(img));
        @SuppressWarnings({ "unchecked", "rawtypes" }) final RandomAccessible<FloatType> source = DetectionUtil.asExtendedFloat((RandomAccessibleInterval) zeroMin);
        /*
			 * Transform ROI in higher level.
			 */
        final Interval interval;
        if (null == roi) {
            interval = zeroMin;
        } else {
            final double[] minSource = new double[3];
            final double[] maxSource = new double[3];
            roi.realMin(minSource);
            roi.realMax(maxSource);
            final double[] minTarget = new double[3];
            final double[] maxTarget = new double[3];
            final AffineTransform3D mipmapTransform = DetectionUtil.getMipmapTransform(sources, tp, setup, level);
            mipmapTransform.applyInverse(minTarget, minSource);
            mipmapTransform.applyInverse(maxTarget, maxSource);
            // Only take 2D or 3D version of the transformed interval.
            final long[] tmin = new long[zeroMin.numDimensions()];
            final long[] tmax = new long[zeroMin.numDimensions()];
            for (int d = 0; d < zeroMin.numDimensions(); d++) {
                tmin[d] = (long) Math.ceil(minTarget[d]);
                tmax[d] = (long) Math.floor(maxTarget[d]);
            }
            final FinalInterval transformedRoi = new FinalInterval(tmin, tmax);
            interval = Intervals.intersect(transformedRoi, zeroMin);
        }
        // Ensure that the interval size is at least 3 in all dimensions.
        final long[] min = new long[interval.numDimensions()];
        interval.min(min);
        final long[] max = new long[interval.numDimensions()];
        interval.max(max);
        for (int d = 0; d < interval.numDimensions(); d++) if (interval.dimension(d) < 3) {
            min[d]--;
            max[d]++;
        }
        final FinalInterval minInterval = new FinalInterval(min, max);
        /*
			 * Process image.
			 */
        final int stepsPerOctave = 4;
        final double k = Math.pow(2.0, 1.0 / stepsPerOctave);
        final double sigma = radius / Math.sqrt(zeroMin.numDimensions());
        final double sigmaSmaller = sigma;
        final double sigmaLarger = k * sigmaSmaller;
        final double normalization = ((detectionType == DetectionType.MAXIMA) ? 1.0 : -1.0) / (sigmaLarger / sigmaSmaller - 1.0);
        final double[] pixelSize = DetectionUtil.getPixelSize(sources, tp, setup, level);
        final DogDetection<FloatType> dog = new DogDetection<>(source, minInterval, pixelSize, sigmaSmaller, sigmaLarger, (detectionType == DetectionType.MAXIMA) ? ExtremaType.MAXIMA : ExtremaType.MINIMA, threshold, true);
        dog.setExecutorService(threadService.getExecutorService());
        final ArrayList<RefinedPeak<Point>> refinedPeaks = dog.getSubpixelPeaks();
        final double[] pos = new double[3];
        final RealPoint sp = RealPoint.wrap(pos);
        final RealPoint p3d = new RealPoint(3);
        final AffineTransform3D transform = DetectionUtil.getTransform(sources, tp, setup, level);
        final DetectionCreator detectionCreator = detectionCreatorFactory.create(tp);
        detectionCreator.preAddition();
        try {
            for (final RefinedPeak<Point> p : refinedPeaks) {
                final double value = p.getValue();
                final double normalizedValue = value * normalization;
                /*
					 * In case p is 2D we pass it to a 3D RealPoint to work
					 * nicely with the 3D transform.
					 */
                for (int d = 0; d < p.numDimensions(); d++) p3d.setPosition(p.getDoublePosition(d), d);
                transform.apply(p3d, sp);
                detectionCreator.createDetection(pos, radius, normalizedValue);
            }
        } finally {
            detectionCreator.postAddition();
        }
    }
    final long end = System.currentTimeMillis();
    processingTime = end - start;
    statusService.clearStatus();
    ok = true;
}
Also used : Point(net.imglib2.Point) RealPoint(net.imglib2.RealPoint) Point(net.imglib2.Point) RealPoint(net.imglib2.RealPoint) FloatType(net.imglib2.type.numeric.real.FloatType) DetectionCreator(org.mastodon.tracking.detection.DetectionCreatorFactory.DetectionCreator) DogDetection(net.imglib2.algorithm.dog.DogDetection) RealPoint(net.imglib2.RealPoint) FinalInterval(net.imglib2.FinalInterval) RefinedPeak(net.imglib2.algorithm.localextrema.RefinedPeak) RandomAccessibleInterval(net.imglib2.RandomAccessibleInterval) FinalInterval(net.imglib2.FinalInterval) Interval(net.imglib2.Interval) AffineTransform3D(net.imglib2.realtransform.AffineTransform3D)

Aggregations

FinalInterval (net.imglib2.FinalInterval)2 Interval (net.imglib2.Interval)2 Point (net.imglib2.Point)2 RandomAccessibleInterval (net.imglib2.RandomAccessibleInterval)2 RealPoint (net.imglib2.RealPoint)2 RefinedPeak (net.imglib2.algorithm.localextrema.RefinedPeak)2 AffineTransform3D (net.imglib2.realtransform.AffineTransform3D)2 FloatType (net.imglib2.type.numeric.real.FloatType)2 DetectionCreator (org.mastodon.tracking.detection.DetectionCreatorFactory.DetectionCreator)2 DogDetection (net.imglib2.algorithm.dog.DogDetection)1 IntervalView (net.imglib2.view.IntervalView)1