/* * 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.abst.feature.tracker; import boofcv.abst.feature.detect.interest.ConfigGeneralDetector; import boofcv.alg.misc.GImageMiscOps; import boofcv.alg.tracker.klt.*; import boofcv.factory.feature.tracker.FactoryPointTracker; import boofcv.struct.image.GrayF32; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * @author Peter Abeles */ public class TestPointTrackerKltPyramid extends StandardPointTracker<GrayF32> { PkltConfig config; public TestPointTrackerKltPyramid() { super(false, true); } @Override public PointTracker<GrayF32> createTracker() { config = new PkltConfig(); return FactoryPointTracker.klt(config, new ConfigGeneralDetector(200, 3, 1000, 0, true), GrayF32.class, GrayF32.class); } /** * Checks to see if tracks are correctly recycled by process and spawn */ @Test public void checkRecycle_Process_Spawn() { PointTrackerKltPyramid<GrayF32,GrayF32> alg = (PointTrackerKltPyramid<GrayF32,GrayF32>)createTracker(); alg.process(image); alg.spawnTracks(); int total = alg.active.size(); assertTrue(total > 0); assertEquals(0,alg.dropped.size()); // drastically change the image causing tracks to be dropped GImageMiscOps.fill(image, 0); alg.process(image); int difference = total - alg.active.size(); assertEquals(difference,alg.dropped.size()); assertEquals(difference,alg.unused.size()); } @Test public void checkRecycleDropAll() { PointTrackerKltPyramid<GrayF32,GrayF32> alg = (PointTrackerKltPyramid<GrayF32,GrayF32>)createTracker(); alg.process(image); alg.spawnTracks(); int numSpawned = alg.active.size(); assertTrue( numSpawned > 0 ); alg.dropAllTracks(); assertEquals( 0, alg.active.size()); assertEquals( 0, alg.dropped.size()); assertEquals( numSpawned, alg.unused.size()); } @Test public void checkRecycleDropTrack() { PointTrackerKltPyramid<GrayF32,GrayF32> alg = (PointTrackerKltPyramid<GrayF32,GrayF32>)createTracker(); assertEquals(0,alg.unused.size()); alg.process(image); alg.spawnTracks(); int before = alg.active.size(); assertTrue( before > 2 ); PyramidKltFeature f = alg.active.get(2); alg.dropTrack((PointTrack)f.cookie); assertEquals( before-1, alg.active.size()); assertEquals(1,alg.unused.size()); } @Test public void addTrack() { PointTrackerKltPyramid<GrayF32,GrayF32> alg = (PointTrackerKltPyramid<GrayF32,GrayF32>)createTracker(); alg.process(image); PointTrack track = alg.addTrack(10,20.5); assertTrue(track != null ); assertEquals(10,track.x,1e-5); assertEquals(20.5,track.y,1e-5); PyramidKltFeature desc = track.getDescription(); assertEquals(10,desc.x,1e-5); assertEquals(20.5,desc.y,1e-5); for(KltFeature f : desc.desc ) { assertTrue(f.Gxx != 0 ); } } /** * The center of tracks should all be inside the image after process() has been called */ @Test public void process_allPointsInside() { PointTrackerKltPyramid<GrayF32,GrayF32> alg = (PointTrackerKltPyramid<GrayF32,GrayF32>)createTracker(); alg.process(image); alg.spawnTracks(); // swap in a new tracker which won't change the track states alg.tracker = new DummyTracker(null); int N = alg.active.size(); assertTrue(N>10); // put two tracks outside of the image, but still close enough to be tracked by KLT alg.active.get(0).setPosition(-1,-2); alg.active.get(2).setPosition(image.width+1,image.height); // process it again, location's wont change so two tracks should be dropped since they are outside alg.process(image); assertEquals(2, alg.getDroppedTracks(null).size()); assertEquals(N-2,alg.getActiveTracks(null).size()); } /** * Don't change the track state */ private static class DummyTracker extends PyramidKltTracker { public DummyTracker(KltTracker tracker) { super(tracker); } @Override public boolean setDescription(PyramidKltFeature feature) { return true; } @Override public KltTrackFault track(PyramidKltFeature feature) { return KltTrackFault.SUCCESS; } } }