Search in sources :

Example 11 with FloatArray2D

use of mpi.fruitfly.math.datastructures.FloatArray2D in project TrakEM2 by trakem2.

the class StitchingTEM method makeStripe.

// static public ImageProcessor makeStripe(final Patch p, final double scale, final boolean ignore_patch_transform) {
// return makeStripe(p, null, scale, ignore_patch_transform);
// }
/**
 * @return FloatProcessor.
 * @param ignore_patch_transform will prevent resizing of the ImageProcessor in the event of the Patch having a transform different than identity.
 */
// TODO 2: there is a combination of options that ends up resulting in the actual ImageProcessor of the Patch being returned as is, which is DANGEROUS because it can potentially result in changes in the data.
public static ImageProcessor makeStripe(final Patch p, final Roi roi, final double scale, final boolean ignore_patch_transform) {
    ImagePlus imp = null;
    ImageProcessor ip = null;
    final Loader loader = p.getProject().getLoader();
    // check if using mipmaps and if there is a file for it. If there isn't, most likely this method is being called in an import sequence as grid procedure.
    if (loader.isMipMapsRegenerationEnabled() && loader.checkMipMapFileExists(p, scale)) {
        // Read the transform image from the patch (this way we avoid the JPEG artifacts)
        final Patch.PatchImage pai = p.createTransformedImage();
        pai.target.setMinAndMax(p.getMin(), p.getMax());
        // p.getProject().getLoader().fetchImage(p, scale);
        Image image = pai.target.createImage();
        // Utils.log2("patch w,h " + p.getWidth() + ", " + p.getHeight() + " fetched image w,h: " + image.getWidth(null) + ", " + image.getHeight(null));
        if (Math.abs(p.getWidth() * scale - image.getWidth(null)) > 0.001 || Math.abs(p.getHeight() * scale - image.getHeight(null)) > 0.001) {
            // slow but good quality. Makes an RGB image, but it doesn't matter.
            image = image.getScaledInstance((int) (p.getWidth() * scale), (int) (p.getHeight() * scale), Image.SCALE_AREA_AVERAGING);
        // Utils.log2("   resizing, now image w,h: " + image.getWidth(null) + ", " + image.getHeight(null));
        }
        try {
            imp = new ImagePlus("s", image);
            ip = imp.getProcessor();
        // imp.show();
        } catch (final Exception e) {
            IJError.print(e);
        }
        // cut
        if (null != roi) {
            // scale ROI!
            Rectangle rb = roi.getBounds();
            final Roi roi2 = new Roi((int) (rb.x * scale), (int) (rb.y * scale), (int) (rb.width * scale), (int) (rb.height * scale));
            rb = roi2.getBounds();
            if (ip.getWidth() != rb.width || ip.getHeight() != rb.height) {
                ip.setRoi(roi2);
                ip = ip.crop();
            }
        }
    // Utils.log2("scale: " + scale + "  ip w,h: " + ip.getWidth() + ", " + ip.getHeight());
    } else {
        final Patch.PatchImage pai = p.createTransformedImage();
        pai.target.setMinAndMax(p.getMin(), p.getMax());
        ip = pai.target;
        imp = new ImagePlus("", ip);
        // compare and adjust
        if (!ignore_patch_transform && p.getAffineTransform().getType() != AffineTransform.TYPE_TRANSLATION) {
            // if it's not only a translation:
            final Rectangle b = p.getBoundingBox();
            ip = ip.resize(b.width, b.height);
        // Utils.log2("resizing stripe for patch: " + p);
        // the above is only meant to correct for improperly acquired images at the microscope, the scale only.
        }
        // cut
        if (null != roi) {
            final Rectangle rb = roi.getBounds();
            if (ip.getWidth() != rb.width || ip.getHeight() != rb.height) {
                ip.setRoi(roi);
                ip = ip.crop();
            }
        }
        // scale
        if (scale < 1) {
            // floats have 4 bytes, plus some java peripherals correction factor
            p.getProject().getLoader().releaseToFit((long) (ip.getWidth() * ip.getHeight() * 4 * 1.2));
            ip = ip.convertToFloat();
            // scaling with area averaging is the same as a gaussian of sigma 0.5/scale and then resize with nearest neightbor So this line does the gaussian, and line below does the neares-neighbor scaling
            ip.setPixels(ImageFilter.computeGaussianFastMirror(new FloatArray2D((float[]) ip.getPixels(), ip.getWidth(), ip.getHeight()), Math.sqrt(0.25 / scale / scale - 0.25)).data);
            // scale maintaining aspect ratio
            ip = ip.resize((int) (ip.getWidth() * scale));
        }
    }
    // return a FloatProcessor
    if (imp.getType() != ImagePlus.GRAY32)
        return ip.convertToFloat();
    return ip;
}
Also used : ImageProcessor(ij.process.ImageProcessor) FloatArray2D(mpi.fruitfly.math.datastructures.FloatArray2D) Rectangle(java.awt.Rectangle) Loader(ini.trakem2.persistence.Loader) Image(java.awt.Image) ImagePlus(ij.ImagePlus) Patch(ini.trakem2.display.Patch) Roi(ij.gui.Roi)

Example 12 with FloatArray2D

use of mpi.fruitfly.math.datastructures.FloatArray2D in project TrakEM2 by trakem2.

the class CrossCorrelation2D method computeCrossCorrelationMT.

/**
 * Computes a translational registration with the help of the cross correlation measure. <br>
 * Limits the overlap to 30% and restricts the shift furthermore by a factor you can tell him
 * (this is useful if you f. ex. know that the vertical shift is much less than the horizontal).
 *
 * NOTE: Works multithreaded
 *
 * @param relMinOverlapX double - if you want to scan for less possible translations seen from a direct overlay,
 * give the relative factor here (e.g. 0.3 means DONOT scan the outer 30%)
 * NOTE: Below 0.05 does not really make sense as you then compare only very few pixels (even one) on the edges
 * which gives then an R of 1 (perfect match)
 * @param relMinOverlapY double - if you want to scan for less possible translations seen from a direct overlay,
 * give the relative factor here (e.g. 0.3 means DONOT scan the outer 30%)
 * NOTE: Below 0.05 does not really make sense as you then compare only very few pixels (even one) on the edges
 * which gives then an R of 1 (perfect match)
 * @param showImages boolean - Show the result of the cross correlation translation
 * @return double[] return a double array containing {displaceX, displaceY, R}
 */
public double[] computeCrossCorrelationMT(final double relMinOverlapX, final double relMinOverlapY, final boolean showImages) {
    // final double relMinOverlap = 0.30;
    final int w1 = img1.width;
    final int w2 = img2.width;
    final int h1 = img1.height;
    final int h2 = img2.height;
    final int min_border_w = (int) (w1 < w2 ? w1 * relMinOverlapX + 0.5 : w2 * relMinOverlapX + 0.5);
    final int min_border_h = (int) (h1 < h2 ? h1 * relMinOverlapY + 0.5 : h2 * relMinOverlapY + 0.5);
    /*System.out.println(w1 + " " + h1 + " " + w2 + " " + h2);
        System.out.println(min_border_w + " " + min_border_h);
        System.out.println("Y [" + (-h2 + min_border_h) + " , " + (h1 - min_border_h) + "]");*/
    final AtomicInteger ai = new AtomicInteger(-w1 + min_border_w);
    Thread[] threads = MultiThreading.newThreads();
    for (int ithread = 0; ithread < threads.length; ++ithread) threads[ithread] = new Thread(new Runnable() {

        public void run() {
            for (int moveX = ai.getAndIncrement(); moveX < w2 - min_border_w; moveX = ai.getAndIncrement()) {
                for (int moveY = -h1 + min_border_h; moveY < h2 - min_border_h; moveY++) {
                    // compute average
                    double avg1 = 0, avg2 = 0;
                    int count = 0;
                    double value1, value2;
                    // for (int x1 = 0; x1 < w1; x1++)
                    for (int x1 = -min(0, moveX); x1 < min(w1, w2 - moveX); x1++) {
                        int x2 = x1 + moveX;
                        // for (int y1 = 0; y1 < h1; y1++)
                        for (int y1 = -min(0, moveY); y1 < min(h1, h2 - moveY); y1++) {
                            int y2 = y1 + moveY;
                            /*if (y2 < 0 || y2 > h2 - 1)
                                        continue;*/
                            value1 = img1.get(x1, y1);
                            if (value1 == -1)
                                continue;
                            value2 = img2.get(x2, y2);
                            if (value2 == -1)
                                continue;
                            avg1 += value1;
                            avg2 += value2;
                            count++;
                        }
                    }
                    if (0 == count)
                        continue;
                    avg1 /= (double) count;
                    avg2 /= (double) count;
                    double var1 = 0, var2 = 0;
                    double coVar = 0;
                    double dist1, dist2;
                    // for (int x1 = 0; x1 < w1; x1++)
                    for (int x1 = -min(0, moveX); x1 < min(w1, w2 - moveX); x1++) {
                        int x2 = x1 + moveX;
                        // for (int y1 = 0; y1 < h1; y1++)
                        for (int y1 = -min(0, moveY); y1 < min(h1, h2 - moveY); y1++) {
                            int y2 = y1 + moveY;
                            /*if (y2 < 0 || y2 > h2 - 1)
                                        continue;*/
                            value1 = img1.get(x1, y1);
                            if (value1 == -1)
                                continue;
                            value2 = img2.get(x2, y2);
                            if (value2 == -1)
                                continue;
                            dist1 = value1 - avg1;
                            dist2 = value2 - avg2;
                            coVar += dist1 * dist2;
                            var1 += dist1 * dist1;
                            var2 += dist2 * dist2;
                        }
                    }
                    var1 /= (double) count;
                    var2 /= (double) count;
                    coVar /= (double) count;
                    double stDev1 = Math.sqrt(var1);
                    double stDev2 = Math.sqrt(var2);
                    // compute correlation coeffienct
                    double R = coVar / (stDev1 * stDev2);
                    compareAndSetR(R, moveX, moveY);
                    if (R < -1 || R > 1) {
                        System.out.println("BIG ERROR! R =" + R);
                    }
                }
            // System.out.println(moveX + " [" + (-w2 + min_border_w) + ", " + (w1 - min_border_w) + "] + best R: " + maxR + " " + displaceX + " " + displaceY);
            }
        }
    });
    MultiThreading.startAndJoin(threads);
    if (showImages) {
        System.out.println(-displaceX + " " + -displaceY + " " + maxR);
        FloatArray2D result = drawTranslatedImages(img1, img2, new Point(-displaceX, -displaceY), DRAWTYPE_OVERLAP);
        FloatArrayToImagePlus(result, "result", 0, 0).show();
    }
    return new double[] { -displaceX, -displaceY, maxR };
}
Also used : ImageToFloatArray2D(mpi.fruitfly.general.ImageArrayConverter.ImageToFloatArray2D) FloatArray2D(mpi.fruitfly.math.datastructures.FloatArray2D) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Point(java.awt.Point) Point(java.awt.Point)

Example 13 with FloatArray2D

use of mpi.fruitfly.math.datastructures.FloatArray2D in project TrakEM2 by trakem2.

the class ImageFilter method distortSamplingY.

public static FloatArray2D distortSamplingY(final FloatArray2D input) {
    final FloatArray2D output = new FloatArray2D(input.width, input.height);
    final int filterSize = 3;
    float avg;
    final Random rnd = new Random(7893469);
    for (int y = 0; y < input.height; y++) {
        final FloatArray2D kernel = new FloatArray2D(1, 3);
        final float random = (rnd.nextFloat() - 0.5f) * 2;
        float val1, val2, val3;
        if (random < 0) {
            val1 = -random;
            val2 = 1 + random;
            val3 = 0;
        } else {
            val3 = random;
            val2 = 1 - random;
            val1 = 0;
        }
        kernel.set(val1, 0, 0);
        kernel.set(val2, 0, 1);
        kernel.set(val3, 0, 2);
        for (int x = 0; x < input.width; x++) {
            avg = 0;
            for (int fy = -filterSize / 2; fy <= filterSize / 2; fy++) {
                try {
                    avg += input.get(x, y + fy) * kernel.get(0, fy + filterSize / 2);
                } catch (final Exception e) {
                }
                ;
            }
            output.set(avg, x, y);
        }
    }
    return output;
}
Also used : FloatArray2D(mpi.fruitfly.math.datastructures.FloatArray2D) Random(java.util.Random)

Example 14 with FloatArray2D

use of mpi.fruitfly.math.datastructures.FloatArray2D in project TrakEM2 by trakem2.

the class ImageFilter method distortSamplingX.

public static FloatArray2D distortSamplingX(final FloatArray2D input) {
    final FloatArray2D output = new FloatArray2D(input.width, input.height);
    final int filterSize = 3;
    float avg;
    final Random rnd = new Random(353245632);
    for (int x = 0; x < input.width; x++) {
        final FloatArray2D kernel = new FloatArray2D(3, 1);
        final float random = (rnd.nextFloat() - 0.5f) * 2;
        float val1, val2, val3;
        if (random < 0) {
            val1 = -random;
            val2 = 1 + random;
            val3 = 0;
        } else {
            val3 = random;
            val2 = 1 - random;
            val1 = 0;
        }
        kernel.set(val1, 0, 0);
        kernel.set(val2, 1, 0);
        kernel.set(val3, 2, 0);
        for (int y = 0; y < input.height; y++) {
            avg = 0;
            for (int fx = -filterSize / 2; fx <= filterSize / 2; fx++) {
                try {
                    avg += input.get(x + fx, y) * kernel.get(fx + filterSize / 2, 0);
                } catch (final Exception e) {
                }
                ;
            }
            output.set(avg, x, y);
        }
    }
    return output;
}
Also used : FloatArray2D(mpi.fruitfly.math.datastructures.FloatArray2D) Random(java.util.Random)

Example 15 with FloatArray2D

use of mpi.fruitfly.math.datastructures.FloatArray2D in project TrakEM2 by trakem2.

the class ImageFilter method computeGaussianFastMirror.

public static FloatArray2D computeGaussianFastMirror(final FloatArray2D input, final double sigma) {
    final FloatArray2D output = new FloatArray2D(input.width, input.height);
    float avg, kernelsum = 0;
    final float[] kernel = createGaussianKernel1D(sigma, true);
    final int filterSize = kernel.length;
    // get kernel sum
    for (final double value : kernel) kernelsum += value;
    // fold in x
    for (int x = 0; x < input.width; x++) for (int y = 0; y < input.height; y++) {
        avg = 0;
        if (x - filterSize / 2 >= 0 && x + filterSize / 2 < input.width)
            for (int f = -filterSize / 2; f <= filterSize / 2; f++) avg += input.get(x + f, y) * kernel[f + filterSize / 2];
        else
            for (int f = -filterSize / 2; f <= filterSize / 2; f++) avg += input.getMirror(x + f, y) * kernel[f + filterSize / 2];
        output.set(avg / kernelsum, x, y);
    }
    // fold in y
    final float[] temp = new float[input.height];
    for (int x = 0; x < input.width; x++) {
        for (int y = 0; y < input.height; y++) {
            avg = 0;
            if (y - filterSize / 2 >= 0 && y + filterSize / 2 < input.height)
                for (int f = -filterSize / 2; f <= filterSize / 2; f++) avg += output.get(x, y + f) * kernel[f + filterSize / 2];
            else
                for (int f = -filterSize / 2; f <= filterSize / 2; f++) avg += output.getMirror(x, y + f) * kernel[f + filterSize / 2];
            temp[y] = avg / kernelsum;
        }
        for (int y = 0; y < input.height; y++) output.set(temp[y], x, y);
    }
    return output;
}
Also used : FloatArray2D(mpi.fruitfly.math.datastructures.FloatArray2D)

Aggregations

FloatArray2D (mpi.fruitfly.math.datastructures.FloatArray2D)21 Point (java.awt.Point)6 ImageProcessor (ij.process.ImageProcessor)4 ImagePlus (ij.ImagePlus)2 Roi (ij.gui.Roi)2 ByteProcessor (ij.process.ByteProcessor)2 FloatProcessor (ij.process.FloatProcessor)2 ShortProcessor (ij.process.ShortProcessor)2 FloatProcessorT2 (ini.trakem2.imaging.FloatProcessorT2)2 Rectangle (java.awt.Rectangle)2 Random (java.util.Random)2 ImageToFloatArray2D (mpi.fruitfly.general.ImageArrayConverter.ImageToFloatArray2D)2 Patch (ini.trakem2.display.Patch)1 Loader (ini.trakem2.persistence.Loader)1 Image (java.awt.Image)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 CrossCorrelation2D (mpi.fruitfly.registration.CrossCorrelation2D)1 PhaseCorrelationPeak (mpicbg.imglib.algorithm.fft.PhaseCorrelationPeak)1 Point (mpicbg.models.Point)1