Search in sources :

Example 11 with Point2D_I16

use of georegression.struct.point.Point2D_I16 in project BoofCV by lessthanoptimal.

the class GeneralToInterestPoint method detect.

@Override
public void detect(T input) {
    super.detect(input, null);
    foundPoints.reset();
    if (getDetector().isDetectMaximums()) {
        QueueCorner corners = detector.getMaximums();
        for (int i = 0; i < corners.size; i++) {
            Point2D_I16 p = corners.get(i);
            foundPoints.grow().set(p.x, p.y);
        }
    }
    if (getDetector().isDetectMinimums()) {
        QueueCorner corners = detector.getMinimums();
        for (int i = 0; i < corners.size; i++) {
            Point2D_I16 p = corners.get(i);
            foundPoints.grow().set(p.x, p.y);
        }
    }
}
Also used : Point2D_I16(georegression.struct.point.Point2D_I16) QueueCorner(boofcv.struct.QueueCorner)

Example 12 with Point2D_I16

use of georegression.struct.point.Point2D_I16 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 Point2D_I16

use of georegression.struct.point.Point2D_I16 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 Point2D_I16

use of georegression.struct.point.Point2D_I16 in project BoofCV by lessthanoptimal.

the class FeaturePyramid method detectCandidateFeatures.

/**
 * Use the feature detector to find candidate features in each level.  Only compute the needed image derivatives.
 */
private void detectCandidateFeatures(T image, double sigma) {
    // adjust corner intensity threshold based upon the current scale factor
    float scaleThreshold = (float) (baseThreshold / Math.pow(sigma, scalePower));
    detector.setThreshold(scaleThreshold);
    computeDerivative.setInput(image);
    D derivX = null, derivY = null;
    D derivXX = null, derivYY = null, derivXY = null;
    if (detector.getRequiresGradient()) {
        derivX = computeDerivative.getDerivative(true);
        derivY = computeDerivative.getDerivative(false);
    }
    if (detector.getRequiresHessian()) {
        derivXX = computeDerivative.getDerivative(true, true);
        derivYY = computeDerivative.getDerivative(false, false);
        derivXY = computeDerivative.getDerivative(true, false);
    }
    detector.process(image, derivX, derivY, derivXX, derivYY, derivXY);
    intensities[spaceIndex].reshape(image.width, image.height);
    intensities[spaceIndex].setTo(detector.getIntensity());
    List<Point2D_I16> m = maximums[spaceIndex];
    m.clear();
    QueueCorner q = detector.getMaximums();
    for (int i = 0; i < q.size; i++) {
        m.add(q.get(i).copy());
    }
    spaceIndex++;
    if (spaceIndex >= 3)
        spaceIndex = 0;
}
Also used : Point2D_I16(georegression.struct.point.Point2D_I16) QueueCorner(boofcv.struct.QueueCorner) ScalePoint(boofcv.struct.feature.ScalePoint)

Example 15 with Point2D_I16

use of georegression.struct.point.Point2D_I16 in project BoofCV by lessthanoptimal.

the class GeneralFeatureDetector method process.

/**
 * Computes point features from image gradients.
 *
 * @param image   Original image.
 * @param derivX  image derivative in along the x-axis. Only needed if {@link #getRequiresGradient()} is true.
 * @param derivY  image derivative in along the y-axis. Only needed if {@link #getRequiresGradient()} is true.
 * @param derivXX Second derivative.  Only needed if {@link #getRequiresHessian()} ()} is true.
 * @param derivXY Second derivative.  Only needed if {@link #getRequiresHessian()} ()} is true.
 * @param derivYY Second derivative.  Only needed if {@link #getRequiresHessian()} ()} is true.
 */
public void process(I image, D derivX, D derivY, D derivXX, D derivYY, D derivXY) {
    intensity.process(image, derivX, derivY, derivXX, derivYY, derivXY);
    GrayF32 intensityImage = intensity.getIntensity();
    int numSelectMin = -1;
    int numSelectMax = -1;
    if (maxFeatures > 0) {
        if (intensity.localMinimums())
            numSelectMin = excludeMinimum == null ? maxFeatures : maxFeatures - excludeMinimum.size;
        if (intensity.localMaximums())
            numSelectMax = excludeMaximum == null ? maxFeatures : maxFeatures - excludeMaximum.size;
        // return without processing if there is no room to detect any more features
        if (numSelectMin <= 0 && numSelectMax <= 0)
            return;
    }
    // mark pixels that should be excluded
    if (excludeMinimum != null) {
        for (int i = 0; i < excludeMinimum.size; i++) {
            Point2D_I16 p = excludeMinimum.get(i);
            intensityImage.set(p.x, p.y, -Float.MAX_VALUE);
        }
    }
    if (excludeMaximum != null) {
        for (int i = 0; i < excludeMaximum.size; i++) {
            Point2D_I16 p = excludeMaximum.get(i);
            intensityImage.set(p.x, p.y, Float.MAX_VALUE);
        }
    }
    foundMinimum.reset();
    foundMaximum.reset();
    if (intensity.hasCandidates()) {
        extractor.process(intensityImage, intensity.getCandidatesMin(), intensity.getCandidatesMax(), foundMinimum, foundMaximum);
    } else {
        extractor.process(intensityImage, null, null, foundMinimum, foundMaximum);
    }
    // optionally select the most intense features only
    selectBest(intensityImage, foundMinimum, numSelectMin, false);
    selectBest(intensityImage, foundMaximum, numSelectMax, true);
}
Also used : GrayF32(boofcv.struct.image.GrayF32) Point2D_I16(georegression.struct.point.Point2D_I16)

Aggregations

Point2D_I16 (georegression.struct.point.Point2D_I16)27 QueueCorner (boofcv.struct.QueueCorner)12 GrayF32 (boofcv.struct.image.GrayF32)7 ScalePoint (boofcv.struct.feature.ScalePoint)5 ConfigExtract (boofcv.abst.feature.detect.extract.ConfigExtract)3 NonMaxSuppression (boofcv.abst.feature.detect.extract.NonMaxSuppression)3 Test (org.junit.Test)3 ImageBorder_F32 (boofcv.core.image.border.ImageBorder_F32)2 FactoryIntensityPoint (boofcv.factory.feature.detect.intensity.FactoryIntensityPoint)2 FactoryDetectPoint (boofcv.factory.feature.detect.interest.FactoryDetectPoint)2 ConvertBufferedImage (boofcv.io.image.ConvertBufferedImage)2 LineParametric2D_F32 (georegression.struct.line.LineParametric2D_F32)2 Point2D_F64 (georegression.struct.point.Point2D_F64)2 BufferedImage (java.awt.image.BufferedImage)2 DescribeRegionPoint (boofcv.abst.feature.describe.DescribeRegionPoint)1 ConfigGeneralDetector (boofcv.abst.feature.detect.interest.ConfigGeneralDetector)1 DetectorFastNaive (boofcv.alg.feature.detect.intensity.DetectorFastNaive)1 EasyGeneralFeatureDetector (boofcv.alg.feature.detect.interest.EasyGeneralFeatureDetector)1 GeneralFeatureDetector (boofcv.alg.feature.detect.interest.GeneralFeatureDetector)1 OrientationImageAverage (boofcv.alg.feature.orientation.OrientationImageAverage)1