Search in sources :

Example 56 with GrowQueue_I32

use of org.ddogleg.struct.GrowQueue_I32 in project BoofCV by lessthanoptimal.

the class RemoveWatersheds method remove.

/**
 * Removes watersheds from the segmented image.  The input image must be the entire original
 * segmented image and assumes the outside border is filled with values < 0.  To access
 * this image call {@link boofcv.alg.segmentation.watershed.WatershedVincentSoille1991#getOutputBorder()}.
 * Each watershed is assigned the value of an arbitrary neighbor.  4-connect rule is used for neighbors.
 * Doesn't matter if initial segmented was done using another connectivity rule.  The value of each region i
 * s reduced by one at the very end.
 *
 * @param segmented Entire segmented image (including border of -1 values) with watersheds
 */
public void remove(GrayS32 segmented) {
    // very quick sanity check
    if (segmented.get(0, 0) >= 0)
        throw new IllegalArgumentException("The segmented image must contain a border of -1 valued pixels.  See" + " JavaDoc for important details you didn't bother to read about.");
    open.reset();
    connect[0] = -1;
    connect[1] = 1;
    connect[2] = segmented.stride;
    connect[3] = -segmented.stride;
    // step through the inner pixels and find watershed pixels
    for (int y = 1; y < segmented.height - 1; y++) {
        int index = y * segmented.stride + 1;
        for (int x = 1; x < segmented.width - 1; x++, index++) {
            if (segmented.data[index] == 0) {
                open.add(index);
            }
        }
    }
    // assign region values to watersheds until they are all assigned
    while (open.size != 0) {
        open2.reset();
        for (int i = 0; i < open.size; i++) {
            int index = open.get(i);
            // assign it to the first valid region it finds
            for (int j = 0; j < 4; j++) {
                // the outside border in the enlarged segmented image will have -1 and watersheds are 0
                int r = segmented.data[index + connect[j]];
                if (r > 0) {
                    segmented.data[index] = r;
                    break;
                }
            }
            // see if it was not assigned a region
            if (segmented.data[index] == 0) {
                open2.add(index);
            }
        }
        // swap open and open2
        GrowQueue_I32 tmp = open;
        open = open2;
        open2 = tmp;
    }
    // watershed pixels have a value of 0 and have been removed. So change the region ID numbers by 1
    for (int y = 1; y < segmented.height - 1; y++) {
        int index = y * segmented.stride + 1;
        for (int x = 1; x < segmented.width - 1; x++, index++) {
            segmented.data[index]--;
        }
    }
}
Also used : GrowQueue_I32(org.ddogleg.struct.GrowQueue_I32)

Example 57 with GrowQueue_I32

use of org.ddogleg.struct.GrowQueue_I32 in project BoofCV by lessthanoptimal.

the class WatershedVincentSoille1991 method process.

/**
 * <p>
 * Segments the image using initial seeds for each region.  This is often done to avoid
 * over segmentation but requires additional preprocessing and/or knowledge on the image structure.  Initial
 * seeds are specified in the input image 'seeds'.  A seed is any pixel with a value &gt; 0.  New new regions
 * will be created beyond those seeds.  The final segmented image is provided by {@link #getOutput()}.
 * </p>
 *
 * <p>
 * NOTE: If seeds are used then {@link #getTotalRegions()} will not return a correct solution.
 * </p>
 *
 * @param input (Input) Input image
 * @param seeds (Output) Segmented image containing seeds.  Note that all seeds should have a value &gt; 0 and have a
 *              value &le; numRegions.
 */
public void process(GrayU8 input, GrayS32 seeds) {
    InputSanityCheck.checkSameShape(input, seeds);
    removedWatersheds = false;
    output.reshape(input.width + 2, input.height + 2);
    distance.reshape(input.width + 2, input.height + 2);
    ImageMiscOps.fill(output, INIT);
    ImageMiscOps.fill(distance, 0);
    fifo.reset();
    // copy the seeds into the output directory
    for (int y = 0; y < seeds.height; y++) {
        int indexSeeds = seeds.startIndex + y * seeds.stride;
        int indexOut = (y + 1) * output.stride + 1;
        for (int x = 0; x < seeds.width; x++, indexSeeds++, indexOut++) {
            int v = seeds.data[indexSeeds];
            if (v > 0) {
                output.data[indexOut] = v;
            }
        }
    }
    // sort pixels
    sortPixels(input);
    // perform watershed
    for (int i = 0; i < histogram.length; i++) {
        GrowQueue_I32 level = histogram[i];
        if (level.size == 0)
            continue;
        // Go through each pixel at this level and mark them according to their neighbors
        for (int j = 0; j < level.size; j++) {
            int index = level.data[j];
            // from its neighbors
            if (output.data[index] == INIT) {
                output.data[index] = MASK;
                assignNewToNeighbors(index);
            }
        }
        currentDistance = 1;
        fifo.add(MARKER_PIXEL);
        while (true) {
            int p = fifo.popHead();
            // end of a cycle.  Exit the loop if it is done or increase the distance and continue processing
            if (p == MARKER_PIXEL) {
                if (fifo.isEmpty())
                    break;
                else {
                    fifo.add(MARKER_PIXEL);
                    currentDistance++;
                    p = fifo.popHead();
                }
            }
            // look at its neighbors and see if they have been labeled or belong to a watershed
            // and update its distance
            checkNeighborsAssign(p);
        }
        // Ensure that all pixels have a distance of zero
        // Could probably do this a bit more intelligently...
        ImageMiscOps.fill(distance, 0);
    }
}
Also used : GrowQueue_I32(org.ddogleg.struct.GrowQueue_I32)

Example 58 with GrowQueue_I32

use of org.ddogleg.struct.GrowQueue_I32 in project BoofCV by lessthanoptimal.

the class WatershedVincentSoille1991 method process.

/**
 * Perform watershed segmentation on the provided input image.  New basins are created at each local minima.
 *
 * @param input Input gray-scale image.
 */
public void process(GrayU8 input) {
    // input = im_0
    removedWatersheds = false;
    output.reshape(input.width + 2, input.height + 2);
    distance.reshape(input.width + 2, input.height + 2);
    ImageMiscOps.fill(output, INIT);
    ImageMiscOps.fill(distance, 0);
    fifo.reset();
    // sort pixels
    sortPixels(input);
    currentLabel = 0;
    for (int i = 0; i < histogram.length; i++) {
        GrowQueue_I32 level = histogram[i];
        if (level.size == 0)
            continue;
        // Go through each pixel at this level and mark them according to their neighbors
        for (int j = 0; j < level.size; j++) {
            int index = level.data[j];
            output.data[index] = MASK;
            // see if its neighbors has been labeled, if so set its distance and add to queue
            assignNewToNeighbors(index);
        }
        currentDistance = 1;
        fifo.add(MARKER_PIXEL);
        while (true) {
            int p = fifo.popHead();
            // end of a cycle.  Exit the loop if it is done or increase the distance and continue processing
            if (p == MARKER_PIXEL) {
                if (fifo.isEmpty())
                    break;
                else {
                    fifo.add(MARKER_PIXEL);
                    currentDistance++;
                    p = fifo.popHead();
                }
            }
            // look at its neighbors and see if they have been labeled or belong to a watershed
            // and update its distance
            checkNeighborsAssign(p);
        }
        // see if new minima have been discovered
        for (int j = 0; j < level.size; j++) {
            int index = level.get(j);
            // distance associated with p is reset to 0
            distance.data[index] = 0;
            if (output.data[index] == MASK) {
                currentLabel++;
                fifo.add(index);
                output.data[index] = currentLabel;
                // grow the new region into the surrounding connected pixels
                while (!fifo.isEmpty()) {
                    checkNeighborsMasks(fifo.popHead());
                }
            }
        }
    }
}
Also used : GrowQueue_I32(org.ddogleg.struct.GrowQueue_I32)

Example 59 with GrowQueue_I32

use of org.ddogleg.struct.GrowQueue_I32 in project BoofCV by lessthanoptimal.

the class SegmentMeanShift method process.

/**
 * Performs mean-shift segmentation on the input image.   The
 * total number of regions can be found by calling {@link #getNumberOfRegions()}.
 *
 * @param image Image
 * @param output Storage for output image.  Each pixel is set to the region it belongs to.
 */
public void process(T image, GrayS32 output) {
    InputSanityCheck.checkSameShape(image, output);
    // long time0 = System.currentTimeMillis();
    search.process(image);
    // long time1 = System.currentTimeMillis();
    FastQueue<float[]> regionColor = search.getModeColor();
    GrayS32 pixelToRegion = search.getPixelToRegion();
    GrowQueue_I32 regionPixelCount = search.getRegionMemberCount();
    FastQueue<Point2D_I32> modeLocation = search.getModeLocation();
    merge.process(pixelToRegion, regionPixelCount, regionColor, modeLocation);
    // long time2 = System.currentTimeMillis();
    segment.process(pixelToRegion, output, regionPixelCount);
    if (prune != null)
        prune.process(image, output, regionPixelCount, regionColor);
// long time4 = System.currentTimeMillis();
// System.out.println("Search: "+(time1-time0)+" Merge: "+(time2-time1)+
// " segment: "+(time3-time2)+" Prune: "+(time4-time3));
}
Also used : Point2D_I32(georegression.struct.point.Point2D_I32) GrayS32(boofcv.struct.image.GrayS32) GrowQueue_I32(org.ddogleg.struct.GrowQueue_I32)

Example 60 with GrowQueue_I32

use of org.ddogleg.struct.GrowQueue_I32 in project BoofCV by lessthanoptimal.

the class VisOdomDualTrackPnP method addNewTracks.

/**
 * Spawns tracks in each image and associates features together.
 */
private void addNewTracks() {
    trackerLeft.spawnTracks();
    trackerRight.spawnTracks();
    List<PointTrack> newLeft = trackerLeft.getNewTracks(null);
    List<PointTrack> newRight = trackerRight.getNewTracks(null);
    // get a list of new tracks and their descriptions
    addNewToList(inputLeft, newLeft, pointsLeft, descLeft);
    addNewToList(inputRight, newRight, pointsRight, descRight);
    // associate using L2R
    assocL2R.setSource(pointsLeft, descLeft);
    assocL2R.setDestination(pointsRight, descRight);
    assocL2R.associate();
    FastQueue<AssociatedIndex> matches = assocL2R.getMatches();
    // storage for the triangulated location in the camera frame
    Point3D_F64 cameraP3 = new Point3D_F64();
    for (int i = 0; i < matches.size; i++) {
        AssociatedIndex m = matches.get(i);
        PointTrack trackL = newLeft.get(m.src);
        PointTrack trackR = newRight.get(m.dst);
        // declare additional track information stored in each track.  Tracks can be recycled so it
        // might not always need to be declared
        LeftTrackInfo infoLeft = trackL.getCookie();
        if (infoLeft == null)
            trackL.cookie = infoLeft = new LeftTrackInfo();
        RightTrackInfo infoRight = trackR.getCookie();
        if (infoRight == null)
            trackR.cookie = infoRight = new RightTrackInfo();
        Stereo2D3D p2d3d = infoLeft.location;
        // convert pixel observations into normalized image coordinates
        leftImageToNorm.compute(trackL.x, trackL.y, p2d3d.leftObs);
        rightImageToNorm.compute(trackR.x, trackR.y, p2d3d.rightObs);
        // triangulate 3D coordinate in the current camera frame
        if (triangulate.triangulate(p2d3d.leftObs, p2d3d.rightObs, leftToRight, cameraP3)) {
            // put the track into the current keyframe coordinate system
            SePointOps_F64.transform(currToKey, cameraP3, p2d3d.location);
            // save a reference to the matching track in the right camera frame
            infoLeft.right = trackR;
            infoLeft.lastConsistent = infoLeft.lastInlier = tick;
            infoRight.left = trackL;
        } else {
            // triangulation failed, drop track
            trackerLeft.dropTrack(trackL);
            // TODO need way to mark right tracks which are unassociated after this loop
            throw new RuntimeException("This special case needs to be handled!");
        }
    }
    // drop tracks that were not associated
    GrowQueue_I32 unassignedRight = assocL2R.getUnassociatedDestination();
    for (int i = 0; i < unassignedRight.size; i++) {
        int index = unassignedRight.get(i);
        // System.out.println(" unassigned right "+newRight.get(index).x+" "+newRight.get(index).y);
        trackerRight.dropTrack(newRight.get(index));
    }
    GrowQueue_I32 unassignedLeft = assocL2R.getUnassociatedSource();
    for (int i = 0; i < unassignedLeft.size; i++) {
        int index = unassignedLeft.get(i);
        trackerLeft.dropTrack(newLeft.get(index));
    }
// System.out.println("Total left "+trackerLeft.getAllTracks(null).size()+"  right "+trackerRight.getAllTracks(null).size());
// System.out.println("Associated: "+matches.size+" new left "+newLeft.size()+" new right "+newRight.size());
// System.out.println("New Tracks: Total: Left "+trackerLeft.getAllTracks(null).size()+" right "+
// trackerRight.getAllTracks(null).size());
// List<PointTrack> temp = trackerLeft.getActiveTracks(null);
// for( PointTrack t : temp ) {
// if( t.cookie == null )
// System.out.println("BUG!");
// }
// temp = trackerRight.getActiveTracks(null);
// for( PointTrack t : temp ) {
// if( t.cookie == null )
// System.out.println("BUG!");
// }
}
Also used : Point3D_F64(georegression.struct.point.Point3D_F64) PointTrack(boofcv.abst.feature.tracker.PointTrack) Stereo2D3D(boofcv.struct.sfm.Stereo2D3D) DescribeRegionPoint(boofcv.abst.feature.describe.DescribeRegionPoint) AssociatedIndex(boofcv.struct.feature.AssociatedIndex) GrowQueue_I32(org.ddogleg.struct.GrowQueue_I32)

Aggregations

GrowQueue_I32 (org.ddogleg.struct.GrowQueue_I32)60 Test (org.junit.Test)35 Point2D_I32 (georegression.struct.point.Point2D_I32)21 GrayS32 (boofcv.struct.image.GrayS32)10 ArrayList (java.util.ArrayList)7 AssociatedIndex (boofcv.struct.feature.AssociatedIndex)6 Point2D_F64 (georegression.struct.point.Point2D_F64)5 FastQueue (org.ddogleg.struct.FastQueue)5 DetectDescribePoint (boofcv.abst.feature.detdesc.DetectDescribePoint)3 ColorQueue_F32 (boofcv.struct.feature.ColorQueue_F32)3 GrayF32 (boofcv.struct.image.GrayF32)3 GrowQueue_I8 (org.ddogleg.struct.GrowQueue_I8)3 ConvertBufferedImage (boofcv.io.image.ConvertBufferedImage)2 BrightFeature (boofcv.struct.feature.BrightFeature)2 LineGeneral2D_F64 (georegression.struct.line.LineGeneral2D_F64)2 Point3D_F64 (georegression.struct.point.Point3D_F64)2 Se3_F64 (georegression.struct.se.Se3_F64)2 Polygon2D_F64 (georegression.struct.shapes.Polygon2D_F64)2 RectangleLength2D_I32 (georegression.struct.shapes.RectangleLength2D_I32)2 BufferedImage (java.awt.image.BufferedImage)2