Search in sources :

Example 11 with ImageBorder_F32

use of boofcv.core.image.border.ImageBorder_F32 in project BoofCV by lessthanoptimal.

the class ImplEdgeNonMaxSuppression method naive8.

/**
 * Slow algorithm which processes the whole image.
 */
public static void naive8(GrayF32 _intensity, GrayS8 direction, GrayF32 output) {
    final int w = _intensity.width;
    final int h = _intensity.height;
    ImageBorder_F32 intensity = (ImageBorder_F32) FactoryImageBorderAlgs.value(_intensity, 0);
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            int dir = direction.get(x, y);
            int dx, dy;
            if (dir == 0 || dir == 4) {
                dx = 1;
                dy = 0;
            } else if (dir == 1 || dir == -3) {
                dx = 1;
                dy = 1;
            } else if (dir == 2 || dir == -2) {
                dx = 0;
                dy = 1;
            } else {
                dx = 1;
                dy = -1;
            }
            float left = intensity.get(x - dx, y - dy);
            float middle = intensity.get(x, y);
            float right = intensity.get(x + dx, y + dy);
            // suppress the value if either of its neighboring values are more than or equal to it
            if (left > middle || right > middle) {
                output.set(x, y, 0);
            } else {
                output.set(x, y, middle);
            }
        }
    }
}
Also used : ImageBorder_F32(boofcv.core.image.border.ImageBorder_F32)

Example 12 with ImageBorder_F32

use of boofcv.core.image.border.ImageBorder_F32 in project BoofCV by lessthanoptimal.

the class FastHessianFeatureDetector method findLocalScaleSpaceMax.

/**
 * Looks for features which are local maximums in the image and scale-space.
 *
 * @param size Size of features in different scale-spaces.
 * @param level Which level in the scale-space
 * @param skip How many pixels are skipped over.
 */
private void findLocalScaleSpaceMax(int[] size, int level, int skip) {
    int index0 = spaceIndex;
    int index1 = (spaceIndex + 1) % 3;
    int index2 = (spaceIndex + 2) % 3;
    ImageBorder_F32 inten0 = (ImageBorder_F32) FactoryImageBorderAlgs.value(intensity[index0], 0);
    GrayF32 inten1 = intensity[index1];
    ImageBorder_F32 inten2 = (ImageBorder_F32) FactoryImageBorderAlgs.value(intensity[index2], 0);
    // find local maximums in image 2D space.  Borders need to be ignored since
    // false positives are found around them as an artifact of pixels outside being
    // treated as being zero.
    foundFeatures.reset();
    extractor.setIgnoreBorder(size[level] / (2 * skip));
    extractor.process(intensity[index1], null, null, null, foundFeatures);
    // Can't consider feature which are right up against the border since they might not be a true local
    // maximum when you consider the features on the other side of the ignore border
    int ignoreRadius = extractor.getIgnoreBorder() + extractor.getSearchRadius();
    int ignoreWidth = intensity[index1].width - ignoreRadius;
    int ignoreHeight = intensity[index1].height - ignoreRadius;
    // number of features which can be added
    int numberRemaining;
    // if configured to do so, only select the features with the highest intensity
    QueueCorner features;
    if (sortBest != null) {
        sortBest.process(intensity[index1], foundFeatures, true);
        features = sortBest.getBestCorners();
        numberRemaining = maxFeaturesPerScale;
    } else {
        features = foundFeatures;
        numberRemaining = Integer.MAX_VALUE;
    }
    int levelSize = size[level];
    int sizeStep = levelSize - size[level - 1];
    // see if these local maximums are also a maximum in scale-space
    for (int i = 0; i < features.size && numberRemaining > 0; i++) {
        Point2D_I16 f = features.get(i);
        // avoid false positives.  see above comment
        if (f.x < ignoreRadius || f.x >= ignoreWidth || f.y < ignoreRadius || f.y >= ignoreHeight)
            continue;
        float val = inten1.get(f.x, f.y);
        // see if it is a max in scale-space too
        if (checkMax(inten0, val, f.x, f.y) && checkMax(inten2, val, f.x, f.y)) {
            // find the feature's location to sub-pixel accuracy using a second order polynomial
            // NOTE: In the original paper this was done using a quadratic.  See comments above.
            // NOTE: Using a 2D polynomial for x and y might produce better results.
            float peakX = polyPeak(inten1.get(f.x - 1, f.y), inten1.get(f.x, f.y), inten1.get(f.x + 1, f.y));
            float peakY = polyPeak(inten1.get(f.x, f.y - 1), inten1.get(f.x, f.y), inten1.get(f.x, f.y + 1));
            float peakS = polyPeak(inten0.get(f.x, f.y), inten1.get(f.x, f.y), inten2.get(f.x, f.y));
            float interpX = (f.x + peakX) * skip;
            float interpY = (f.y + peakY) * skip;
            float interpS = levelSize + peakS * sizeStep;
            double scale = 1.2 * interpS / 9.0;
            foundPoints.grow().set(interpX, interpY, scale);
            numberRemaining--;
        }
    }
}
Also used : GrayF32(boofcv.struct.image.GrayF32) Point2D_I16(georegression.struct.point.Point2D_I16) QueueCorner(boofcv.struct.QueueCorner) ImageBorder_F32(boofcv.core.image.border.ImageBorder_F32) ScalePoint(boofcv.struct.feature.ScalePoint)

Example 13 with ImageBorder_F32

use of boofcv.core.image.border.ImageBorder_F32 in project BoofCV by lessthanoptimal.

the class FeaturePyramid method findLocalScaleSpaceMax.

/**
 * Searches the pyramid layers up and down to see if the found 2D features are also scale space maximums.
 */
protected void findLocalScaleSpaceMax(PyramidFloat<T> ss, int layerID) {
    int index0 = spaceIndex;
    int index1 = (spaceIndex + 1) % 3;
    int index2 = (spaceIndex + 2) % 3;
    List<Point2D_I16> candidates = maximums[index1];
    ImageBorder_F32 inten0 = (ImageBorder_F32) FactoryImageBorderAlgs.value(intensities[index0], 0);
    GrayF32 inten1 = intensities[index1];
    ImageBorder_F32 inten2 = (ImageBorder_F32) FactoryImageBorderAlgs.value(intensities[index2], 0);
    float scale0 = (float) ss.scale[layerID - 1];
    float scale1 = (float) ss.scale[layerID];
    float scale2 = (float) ss.scale[layerID + 1];
    float sigma0 = (float) ss.getSigma(layerID - 1);
    float sigma1 = (float) ss.getSigma(layerID);
    float sigma2 = (float) ss.getSigma(layerID + 1);
    // not sure if this is the correct way to handle the change in scale
    float ss0 = (float) (Math.pow(sigma0, scalePower) / scale0);
    float ss1 = (float) (Math.pow(sigma1, scalePower) / scale1);
    float ss2 = (float) (Math.pow(sigma2, scalePower) / scale2);
    for (Point2D_I16 c : candidates) {
        float val = ss1 * inten1.get(c.x, c.y);
        // find pixel location in each image's local coordinate
        int x0 = (int) (c.x * scale1 / scale0);
        int y0 = (int) (c.y * scale1 / scale0);
        int x2 = (int) (c.x * scale1 / scale2);
        int y2 = (int) (c.y * scale1 / scale2);
        if (checkMax(inten0, val / ss0, x0, y0) && checkMax(inten2, val / ss2, x2, y2)) {
            // put features into the scale of the upper image
            foundPoints.add(new ScalePoint(c.x * scale1, c.y * scale1, sigma1));
        }
    }
}
Also used : Point2D_I16(georegression.struct.point.Point2D_I16) GrayF32(boofcv.struct.image.GrayF32) ScalePoint(boofcv.struct.feature.ScalePoint) ImageBorder_F32(boofcv.core.image.border.ImageBorder_F32) ScalePoint(boofcv.struct.feature.ScalePoint)

Example 14 with ImageBorder_F32

use of boofcv.core.image.border.ImageBorder_F32 in project BoofCV by lessthanoptimal.

the class ImplEdgeNonMaxSuppression method naive4.

/**
 * Slow algorithm which processes the whole image.
 */
public static void naive4(GrayF32 _intensity, GrayS8 direction, GrayF32 output) {
    final int w = _intensity.width;
    final int h = _intensity.height;
    ImageBorder_F32 intensity = (ImageBorder_F32) FactoryImageBorderAlgs.value(_intensity, 0);
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            int dir = direction.get(x, y);
            int dx, dy;
            if (dir == 0) {
                dx = 1;
                dy = 0;
            } else if (dir == 1) {
                dx = 1;
                dy = 1;
            } else if (dir == 2) {
                dx = 0;
                dy = 1;
            } else {
                dx = 1;
                dy = -1;
            }
            float left = intensity.get(x - dx, y - dy);
            float middle = intensity.get(x, y);
            float right = intensity.get(x + dx, y + dy);
            // suppress the value if either of its neighboring values are more than or equal to it
            if (left > middle || right > middle) {
                output.set(x, y, 0);
            } else {
                output.set(x, y, middle);
            }
        }
    }
}
Also used : ImageBorder_F32(boofcv.core.image.border.ImageBorder_F32)

Example 15 with ImageBorder_F32

use of boofcv.core.image.border.ImageBorder_F32 in project BoofCV by lessthanoptimal.

the class ImplEdgeNonMaxSuppression method border4.

/**
 * Just processes the image border.
 */
public static void border4(GrayF32 _intensity, GrayS8 direction, GrayF32 output) {
    int w = _intensity.width;
    int h = _intensity.height - 1;
    ImageBorder_F32 intensity = (ImageBorder_F32) FactoryImageBorderAlgs.value(_intensity, 0);
    // top border
    for (int x = 0; x < w; x++) {
        int dir = direction.get(x, 0);
        int dx, dy;
        if (dir == 0) {
            dx = 1;
            dy = 0;
        } else if (dir == 1) {
            dx = 1;
            dy = 1;
        } else if (dir == 2) {
            dx = 0;
            dy = 1;
        } else {
            dx = 1;
            dy = -1;
        }
        float left = intensity.get(x - dx, -dy);
        float middle = intensity.get(x, 0);
        float right = intensity.get(x + dx, dy);
        if (left > middle || right > middle) {
            output.set(x, 0, 0);
        } else {
            output.set(x, 0, middle);
        }
    }
    // bottom border
    for (int x = 0; x < w; x++) {
        int dir = direction.get(x, h);
        int dx, dy;
        if (dir == 0) {
            dx = 1;
            dy = 0;
        } else if (dir == 1) {
            dx = 1;
            dy = 1;
        } else if (dir == 2) {
            dx = 0;
            dy = 1;
        } else {
            dx = 1;
            dy = -1;
        }
        float left = intensity.get(x - dx, h - dy);
        float middle = intensity.get(x, h);
        float right = intensity.get(x + dx, h + dy);
        if (left > middle || right > middle) {
            output.set(x, h, 0);
        } else {
            output.set(x, h, middle);
        }
    }
    // left border
    for (int y = 1; y < h; y++) {
        int dir = direction.get(0, y);
        int dx, dy;
        if (dir == 0) {
            dx = 1;
            dy = 0;
        } else if (dir == 1) {
            dx = 1;
            dy = 1;
        } else if (dir == 2) {
            dx = 0;
            dy = 1;
        } else {
            dx = 1;
            dy = -1;
        }
        float left = intensity.get(-dx, y - dy);
        float middle = intensity.get(0, y);
        float right = intensity.get(dx, y + dy);
        if (left > middle || right > middle) {
            output.set(0, y, 0);
        } else {
            output.set(0, y, middle);
        }
    }
    // right border
    w = w - 1;
    for (int y = 1; y < h; y++) {
        int dir = direction.get(w, y);
        int dx, dy;
        if (dir == 0) {
            dx = 1;
            dy = 0;
        } else if (dir == 1) {
            dx = 1;
            dy = 1;
        } else if (dir == 2) {
            dx = 0;
            dy = 1;
        } else {
            dx = 1;
            dy = -1;
        }
        float left = intensity.get(w - dx, y - dy);
        float middle = intensity.get(w, y);
        float right = intensity.get(w + dx, y + dy);
        if (left > middle || right > middle) {
            output.set(w, y, 0);
        } else {
            output.set(w, y, middle);
        }
    }
}
Also used : ImageBorder_F32(boofcv.core.image.border.ImageBorder_F32)

Aggregations

ImageBorder_F32 (boofcv.core.image.border.ImageBorder_F32)29 GrayF32 (boofcv.struct.image.GrayF32)20 Test (org.junit.Test)16 Kernel2D_F32 (boofcv.struct.convolve.Kernel2D_F32)7 ImageBorder_S32 (boofcv.core.image.border.ImageBorder_S32)2 ScalePoint (boofcv.struct.feature.ScalePoint)2 GrayS16 (boofcv.struct.image.GrayS16)2 ImageGray (boofcv.struct.image.ImageGray)2 Point2D_I16 (georegression.struct.point.Point2D_I16)2 QueueCorner (boofcv.struct.QueueCorner)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Random (java.util.Random)1