/* * 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.ellipse; import boofcv.alg.misc.ImageMiscOps; import boofcv.alg.misc.PixelMath; import boofcv.struct.image.GrayU8; import georegression.struct.shapes.EllipseRotated_F64; import org.junit.Test; import java.util.ArrayList; import java.util.List; import java.util.Random; import static org.junit.Assert.*; /** * @author Peter Abeles */ public class TestSnapToEllipseEdge { Random rand = new Random(24234); /** * Simple test case involving a fully rendered image and known result */ @Test public void simpleNoChange() { EllipseRotated_F64 target = new EllipseRotated_F64(80,85,50,40,0); EllipseRotated_F64 found = new EllipseRotated_F64(); List<EllipseRotated_F64> ellipses = new ArrayList<>(); ellipses.add( target); GrayU8 image = TestBinaryEllipseDetectorPixel.renderEllipses(200,300,ellipses, 0); SnapToEllipseEdge<GrayU8> alg = new SnapToEllipseEdge<>(30,1,GrayU8.class); alg.setImage(image); assertTrue(alg.process(target,found)); TestBinaryEllipseDetectorPixel.checkEquals(target,found,1.0,0.01); } /** * The ellipse touches the image border */ @Test public void simpleNoChange_border() { EllipseRotated_F64 target = new EllipseRotated_F64(35,85,50,40,0); EllipseRotated_F64 found = new EllipseRotated_F64(); List<EllipseRotated_F64> ellipses = new ArrayList<>(); ellipses.add( target); GrayU8 image = TestBinaryEllipseDetectorPixel.renderEllipses(200,300,ellipses, 0); SnapToEllipseEdge<GrayU8> alg = new SnapToEllipseEdge<>(30,1,GrayU8.class); alg.setImage(image); assertTrue(alg.process(target,found)); TestBinaryEllipseDetectorPixel.checkEquals(target,found,1.0,0.01); } /** * The initial estimate is slightly off */ @Test public void simpleIncorrectEstimate() { EllipseRotated_F64 target = new EllipseRotated_F64(80,85,50,40,0); EllipseRotated_F64 input = new EllipseRotated_F64(target); EllipseRotated_F64 found = new EllipseRotated_F64(); // make the import imprecise input.center.x += 0.5; input.a *= 0.97; input.b *= 1.05; input.phi = 0.04; List<EllipseRotated_F64> ellipses = new ArrayList<>(); ellipses.add( target); GrayU8 image = TestBinaryEllipseDetectorPixel.renderEllipses(200,300,ellipses, 0); SnapToEllipseEdge<GrayU8> alg = new SnapToEllipseEdge<>(30,1,GrayU8.class); alg.setImage(image); assertTrue(alg.process(input,found)); TestBinaryEllipseDetectorPixel.checkEquals(target,found,1.0,0.01); } @Test public void change() { assertEquals(0,SnapToEllipseEdge. change(new EllipseRotated_F64(1,2,3,4,-0.2), new EllipseRotated_F64(1,2,3,4,-0.2)),1e-8); assertEquals(0,SnapToEllipseEdge. change(new EllipseRotated_F64(1,2,3,4,Math.PI/2.0), new EllipseRotated_F64(1,2,3,4,-Math.PI/2.0)),1e-8); assertNotEquals(0,SnapToEllipseEdge. change(new EllipseRotated_F64(1.5,2,3,4,-0.2), new EllipseRotated_F64(1,2,3,4,-0.2)),1e-8); assertNotEquals(0,SnapToEllipseEdge. change(new EllipseRotated_F64(1,2.5,3,4,-0.2), new EllipseRotated_F64(1,2,3,4,-0.2)),1e-8); assertNotEquals(0,SnapToEllipseEdge. change(new EllipseRotated_F64(1,2,3.5,4,-0.2), new EllipseRotated_F64(1,2,3,4,-0.2)),1e-8);; assertNotEquals(0,SnapToEllipseEdge. change(new EllipseRotated_F64(1,2,3,4.5,-0.25), new EllipseRotated_F64(1,2,3,4,-0.2)),1e-8);; } @Test public void computePointsAndWeights() { EllipseRotated_F64 target = new EllipseRotated_F64(80,85,50,40,0); List<EllipseRotated_F64> ellipses = new ArrayList<>(); ellipses.add( target); GrayU8 image = TestBinaryEllipseDetectorPixel.renderEllipses(200,300,ellipses, 0); // add a little bit of noise to prevent perfect zeros from appearing in weights PixelMath.plus(image,10,0,255,image); PixelMath.multiply(image,0.95,0,255,image); ImageMiscOps.addUniform(image,rand,-5,5); int numContour = 20; SnapToEllipseEdge<GrayU8> alg = new SnapToEllipseEdge<>(numContour,1,GrayU8.class); alg.setImage(image); alg.computePointsAndWeights(target); // all sampling was done inside the image and low change of a perfect zero assertEquals(3*numContour,alg.samplePts.size); assertEquals(3*numContour,alg.weights.size); // if the image wasn't discretized the number of zero weight would be 2 times larger than the max values // see if the results approximate that int numLow = 0, numHigh = 0; for (int i = 0; i < alg.weights.size(); i++) { if( alg.weights.data[i] < 90 ) numLow++; else if( alg.weights.data[i] > 120 ) numHigh++; } assertTrue(numLow > numHigh*1.5); } }