/* * Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved. * * This file is part of BoofCV (http://boofcv.org). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package boofcv.alg.shapes.polyline; import georegression.struct.point.Point2D_I32; import org.ddogleg.struct.GrowQueue_I32; import org.junit.Test; import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * @author Peter Abeles */ public class TestSplitMergeLineFitSegment { private static final double MIN_SPLIT = 0.1; /** * Tests contours with zero and one points in them */ @Test public void checkZeroOne() { List<Point2D_I32> contour = new ArrayList<>(); SplitMergeLineFitSegment alg = new SplitMergeLineFitSegment(0.15,MIN_SPLIT,100); alg.process(contour); assertEquals(0,alg.getSplits().size); contour.add( new Point2D_I32(2,3)); alg.process(contour); assertEquals(0,alg.getSplits().size); } /** * Simple case with a zig-zag pattern */ @Test public void simpleCase() { List<Point2D_I32> contour = new ArrayList<>(); for( int i = 0; i < 10; i++ ) contour.add( new Point2D_I32(i,0)); for( int i = 1; i < 5; i++ ) contour.add( new Point2D_I32(9,i)); for( int i = 1; i < 10; i++ ) contour.add( new Point2D_I32(9+i,4)); for( int i = 2; i < 5; i++ ) contour.add( new Point2D_I32(18,5-i)); SplitMergeLineFitSegment alg = new SplitMergeLineFitSegment(0.15,MIN_SPLIT,100); alg.process(contour); GrowQueue_I32 splits = alg.getSplits(); assertEquals(5 , splits.size ); assertEquals(0,alg.splits.data[0]); assertEquals(9,alg.splits.data[1]); assertEquals(13,alg.splits.data[2]); assertEquals(22,alg.splits.data[3]); assertEquals(25,alg.splits.data[4]); } @Test public void splitSegments() { SplitMergeLineFitSegment alg = new SplitMergeLineFitSegment(0.15,MIN_SPLIT,100); alg.contour = new ArrayList<>(); for( int i = 0; i < 10; i++ ) alg.contour.add( new Point2D_I32(i,0)); alg.contour.get(4).y=5; // single split alg.splits.add(0); alg.splits.add(9); assertTrue(alg.splitSegments()); assertEquals(3,alg.splits.size); assertEquals(0,alg.splits.data[0]); assertEquals(4,alg.splits.data[1]); assertEquals(9,alg.splits.data[2]); } @Test public void selectSplitOffset() { SplitMergeLineFitSegment alg = new SplitMergeLineFitSegment(0.15,MIN_SPLIT,100); alg.contour = new ArrayList<>(); for( int i = 0; i < 10; i++ ) alg.contour.add( new Point2D_I32(i,0)); alg.contour.get(4).y = 10; alg.line.slope.x = 5; int found = alg.selectSplitBetween(0, 9); assertEquals(4,found); found = alg.selectSplitBetween(0, 5); assertEquals(4, found); found = alg.selectSplitBetween(0, 4); assertTrue(found < 4); found = alg.selectSplitBetween(0, 3); assertEquals(-1, found); found = alg.selectSplitBetween(5, 9); assertEquals(-1, found); found = alg.selectSplitBetween(1, 6); assertEquals(4, found); } @Test public void mergeSegments() { SplitMergeLineFitSegment alg = new SplitMergeLineFitSegment(0.001,MIN_SPLIT,100); alg.contour = new ArrayList<>(); alg.contour.add(new Point2D_I32(0,0)); alg.contour.add(new Point2D_I32(1,0)); alg.contour.add(new Point2D_I32(3,0)); alg.contour.add(new Point2D_I32(3,4)); alg.contour.add(new Point2D_I32(4,4)); alg.contour.add(new Point2D_I32(5,4)); for( int i = 0; i < alg.contour.size(); i++ ) { alg.splits.add(i); } assertTrue(alg.mergeSegments()); assertEquals(3,alg.splits.size); assertEquals(0,alg.splits.data[0]); assertEquals(2,alg.splits.data[1]); assertEquals(5,alg.splits.data[2]); } /** * Makes sure the selectSplitOffset is obeying the minimumSideLengthPixel parameter */ @Test public void selectSplitBetween_minimumSideLengthPixel() { SplitMergeLineFitSegment alg = new SplitMergeLineFitSegment(0.001,MIN_SPLIT,100); alg.contour = new ArrayList<>(); // contour is straight with one point that's way off for (int i = 0; i < 20; i++) { alg.contour.add(new Point2D_I32(i, 0)); } alg.contour.get(10).set(10,10); // force it to use the default of 1 pixel alg.minimumSideLengthPixel = 0; // shouldn't be affect by the min side assertEquals(10,alg.selectSplitBetween(0,19)); int r = 0; assertEquals(10,alg.selectSplitBetween(10-r-1,10+r+1)); assertEquals(-1,alg.selectSplitBetween(10-r,10+r+1)); assertEquals(-1,alg.selectSplitBetween(10-r-1,10+r)); alg.minimumSideLengthPixel = 2; r = 1; assertEquals(10,alg.selectSplitBetween(10-r-1,10+r+1)); assertEquals(-1,alg.selectSplitBetween(10-r,10+r+1)); assertEquals(-1,alg.selectSplitBetween(10-r-1,10+r)); } /** * Checks to make sure the minimum side length is correctly set */ @Test public void set_minimumSideLengthPixel() { double minSplitFraction = 0.1; List<Point2D_I32> contour = new ArrayList<>(); for (int i = 0; i < 30; i++) { contour.add(new Point2D_I32(i, 0)); } SplitMergeLineFitSegment alg = new SplitMergeLineFitSegment(0.001,minSplitFraction,100); alg.process(contour); assertEquals(contour.size()/10,alg.minimumSideLengthPixel); } }