/** * Scans through the image and record the array index of all marked pixels */ protected void findOnePixels(GrowQueue_I32 ones) { for (int y = 0; y < binary.height; y++) { int index = binary.startIndex + y* binary.stride; for (int x = 0; x < binary.width; x++, index++) { if( binary.data[index] != 0 ) { ones.add(index); } } } }
/** * Does much of the work needed to remove the redundant segments that are being merged into their root node. * The list of member count is updated. mergeList is updated with the new segment IDs. */ protected void setToRootNodeNewID( GrowQueue_I32 regionMemberCount ) { tmpMemberCount.reset(); for( int i = 0; i < mergeList.size; i++ ) { int p = mergeList.data[i]; if( p == i ) { mergeList.data[i] = rootID.data[i]; tmpMemberCount.add( regionMemberCount.data[i] ); } else { mergeList.data[i] = rootID.data[mergeList.data[i]]; } } regionMemberCount.reset(); regionMemberCount.addAll(tmpMemberCount); }
/** * Specifies that the point was observed in this view. * @param pointIndex index of point * @param viewIndex index of view */ public void connectPointToView( int pointIndex , int viewIndex ) { SceneStructureMetric.Point p = points[pointIndex]; for (int i = 0; i < p.views.size; i++) { if( p.views.data[i] == viewIndex ) throw new IllegalArgumentException("Tried to add the same view twice. viewIndex="+viewIndex); } p.views.add(viewIndex); }
private boolean checkSplit(boolean change, int i0 , int i1) { int start = splits.data[i0]; int end = splits.data[i1]; int length = circularDistance(start, end); int bestOffset = selectSplitOffset(start,length); if( bestOffset >= 0 ) { change = true; work.add(start); work.add((start+bestOffset)%N); } else { work.add(start); } return change; }
public void connect(int segment) { if( isConnected(segment)) return; this.edges.add(segment); }
/** * Very fast histogram based sorting. Index of each pixel is placed inside a list for its intensity level. */ protected void sortPixels(GrayU8 input) { // initialize histogram for( int i = 0; i < histogram.length; i++ ) { histogram[i].reset(); } // sort by creating a histogram for( int y = 0; y < input.height; y++ ) { int index = input.startIndex + y*input.stride; int indexOut = (y+1)*output.stride + 1; for (int x = 0; x < input.width; x++ , index++ , indexOut++) { int value = input.data[index] & 0xFF; histogram[value].add(indexOut); } } }
/** * Adds an observation of the specified feature. * @param featureIndex Feature index * @param x pixel x-coordinate * @param y pixel y-coordinate */ public void add( int featureIndex , float x , float y ) { point.add(featureIndex); observations.add(x); observations.add(y); }
/** * Converts the list of shapes into the output format */ private void convertIntoOuput(List<FoundShape> schnabelShapes) { output.reset(); for (int i = 0; i < schnabelShapes.size(); i++) { FoundShape fs = schnabelShapes.get(i); Shape os = output.grow(); os.parameters = fs.modelParam; os.type = shapeList.get(fs.whichShape); os.points.clear(); os.indexes.reset(); // add the points to it for (int j = 0; j < fs.points.size(); j++) { PointVectorNN pv = fs.points.get(j); os.points.add(pv.p); os.indexes.add(pv.index); } } }
@Override public boolean process(List<Point2D_I32> list) { splits.reset(); this.contour = list; if( list.size() <= 2 ) { // can't do anything with two or less points return false; } this.minimumSideLengthPixel = (int)Math.ceil(contour.size()* minimumSideLengthFraction); // initial segmentation splits.add(0); splitPixels(0, list.size() - 1); splits.add(list.size()-1); for( int i = 0; i < maxIterations; i++ ) { boolean changed = mergeSegments(); if( !changed && !splitSegments() ) break; if( splits.size() <= 2 || splits.size() >= abortSplits ) break; } return true; }
synchronized public void addPoint( float x , float y , float z , int rgb ) { cloudXyz.add(x); cloudXyz.add(y); cloudXyz.add(z); cloudColor.add(rgb); } synchronized public void addPoints( float pointsXYZ[] , int pointsRGB[] , int length ) {
/** * Recursively splits pixels. Used in the initial segmentation. Only split points between * the two ends are added */ protected void splitPixels( int indexStart , int indexStop ) { // too short to split if( indexStart+1 >= indexStop ) return; int indexSplit = selectSplitBetween(indexStart, indexStop); if( indexSplit >= 0 ) { splitPixels(indexStart, indexSplit); splits.add(indexSplit); splitPixels(indexSplit, indexStop); } }
private void findBestPoints(int x, int y, List<Point2D_F64> pts , List<Integer> selected ) { double bestDist = clickDistance*clickDistance; GrowQueue_I32 bestIndexes = new GrowQueue_I32(20); for( int i = 0; i < pts.size(); i++ ) { if( !isValidPoint(i) ) continue; Point2D_F64 p = pts.get(i); double d = UtilPoint2D_F64.distanceSq(p.x, p.y, x, y); if( d < bestDist ) { bestDist = d; bestIndexes.reset(); bestIndexes.add(i); } else if( Math.abs(d - bestDist) < 0.01 ) { bestIndexes.add(i); } } if( bestIndexes.size() > 0 ) { int indexRight = bestIndexes.get(0); } for (int i = 0; i < bestIndexes.size(); i++) { selected.add(bestIndexes.get(i)); } }
public GrowQueue_I32 checkSource( FastQueue<AssociatedIndex> matches , int num ) { matched.resize(num); for( int i = 0; i < matched.size; i++ ) { matched.data[i] = 0; } for( int i = 0; i < matches.size; i++ ) { matched.data[matches.get(i).src] = 1; } unassociatedSrc.reset(); for( int i = 0; i < matched.size; i++ ) { if( matched.data[i] == 0 ) { unassociatedSrc.add(i); } } return unassociatedSrc; }
private void addShapeToOutput(List<PointVectorNN> inliers) { ModelFitter<Object, PointVectorNN> fitter = fitters.get(ransac.getModelIndex()); Object shapeParam = models.get(ransac.getModelIndex()); fitter.fitModel(inliers, ransac.getModelParameters(), shapeParam); // convert the results into output format Shape os = output.grow(); os.parameters = modelManagers.get(ransac.getModelIndex()).createModelInstance(); modelManagers.get(ransac.getModelIndex()).copyModel(shapeParam,os.parameters); os.type = shapeList.get(ransac.getModelIndex()); os.points.clear(); os.indexes.reset(); // add the points to it for (int j = 0; j < inliers.size(); j++) { PointVectorNN pv = inliers.get(j); os.points.add(pv.p); os.indexes.add(pv.index); } }
public GrowQueue_I32 checkDestination( FastQueue<AssociatedIndex> matches , int num ) { matched.resize(num); for( int i = 0; i < matched.size; i++ ) { matched.data[i] = 0; } for( int i = 0; i < matches.size; i++ ) { matched.data[matches.get(i).dst] = 1; } unassociatedDst.reset(); for( int i = 0; i < matched.size; i++ ) { if( matched.data[i] == 0 ) { unassociatedDst.add(i); } } return unassociatedDst; } }
/** * Recursively splits pixels between indexStart to indexStart+length. A split happens if there is a pixel * more than the desired distance away from the two end points. Results are placed into 'splits' */ protected void splitPixels(int indexStart, int length) { // too short to split if( length < minimumSideLengthPixel) return; // end points of the line int indexEnd = (indexStart+length)%N; int splitOffset = selectSplitOffset(indexStart,length); if( splitOffset >= 0 ) { // System.out.println(" splitting "); splitPixels(indexStart, splitOffset); int indexSplit = (indexStart+splitOffset)%N; splits.add(indexSplit); splitPixels(indexSplit, circularDistance(indexSplit, indexEnd)); } }
@Override public void associate() { if( listSrc == null ) throw new IllegalArgumentException("source features not specified"); if( listDst == null ) throw new IllegalArgumentException("destination features not specified"); unassocSrc.reset(); alg.associate(listSrc,listDst); int pairs[] = alg.getPairs(); double score[] = alg.getFitQuality(); matches.reset(); for( int i = 0; i < listSrc.size; i++ ) { int dst = pairs[i]; if( dst >= 0 ) matches.grow().setAssociation(i,dst,score[i]); else unassocSrc.add(i); } }
/** * Step 2: If the pixel below is unmarked and white then it must be an internal contour * Same behavior it the pixel in question has been labeled or not already */ private void handleStep2(GrayS32 labeled, int label) { // if the blob is not labeled and in this state it cannot be against the left side of the image if( label == 0 ) label = labeled.data[indexOut-1]; ContourPacked c = contours.get(label-1); c.internalIndexes.add( packedPoints.size() ); packedPoints.grow(); tracer.setMaxContourSize(saveInternalContours?maxContourSize:0); tracer.trace(label,x,y,false); // See if the inner contour exceeded the maximum or minimum size. If so free its points if( packedPoints.sizeOfTail() >= maxContourSize || packedPoints.sizeOfTail() < minContourSize ) { packedPoints.removeTail(); packedPoints.grow(); } }
@Test public void splitData_withData() { List<double[]> points = createPoints(2, 1,2 , 3,5 , -3,4); GrowQueue_I32 data = new GrowQueue_I32(); for( int i = 0; i < points.size(); i++ ) data.add(i); AxisSplitterMedian<double[]> alg = new AxisSplitterMedian<>(distance,new DummyRule(1)); alg.splitData(points,data,left,leftData,right,rightData); assertEquals(1,left.size()); assertEquals(1,right.size()); assertEquals(1,leftData.size()); assertEquals(1,rightData.size()); assertEquals(1,alg.getSplitAxis(),1e-8); assertEquals(-3,alg.getSplitPoint()[0],1e-8); assertTrue(data.get(2) == alg.getSplitIndex()); assertTrue(data.get(0) == leftData.get(0)); assertTrue(data.get(1) == rightData.get(0)); }
@Test public void getFraction() { GrowQueue_I32 alg = new GrowQueue_I32(20); for (int i = 0; i < 20; i++) { alg.add(i); } assertEquals(0,alg.getFraction(0.0)); assertEquals(0,alg.getFraction(0.02)); assertEquals(0,alg.getFraction(0.03)); assertEquals(1,alg.getFraction(1.0/19.0)); assertEquals(1,alg.getFraction(1.7/19.0)); assertEquals(19/2,alg.getFraction(0.5)); assertEquals(19,alg.getFraction(1.0)); } }