boofcv.abst.feature.tracker.PointTrackerCombined Maven / Gradle / Ivy
/*
* Copyright (c) 2011-2017, 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.filter.derivative.ImageGradient;
import boofcv.alg.tracker.combined.CombinedTrack;
import boofcv.alg.tracker.combined.CombinedTrackerScalePoint;
import boofcv.alg.transform.pyramid.PyramidOps;
import boofcv.factory.filter.derivative.FactoryDerivative;
import boofcv.factory.transform.pyramid.FactoryPyramid;
import boofcv.struct.feature.TupleDesc;
import boofcv.struct.image.ImageGray;
import boofcv.struct.image.ImageType;
import boofcv.struct.pyramid.PyramidDiscrete;
import java.util.ArrayList;
import java.util.List;
/**
* Wrapper around {@link CombinedTrackerScalePoint} for {@link PointTracker}. Features are respawned when the
* number of active tracks drops below a threshold automatically. This threshold is realtive to the number
* of tracks spawned previously and is adjusted when the user requests that tracks are dropped.
*
* @author Peter Abeles
*/
// TODO drop after no associate after X detections
// TODO Speed up combination of respawn and spawn
public class PointTrackerCombined, D extends ImageGray, Desc extends TupleDesc>
implements PointTracker {
CombinedTrackerScalePoint tracker;
PyramidDiscrete pyramid;
D[] derivX;
D[] derivY;
Class derivType;
ImageGradient gradient;
int reactivateThreshold;
int previousSpawn;
boolean detected;
public PointTrackerCombined(CombinedTrackerScalePoint tracker,
int reactivateThreshold,
Class imageType, Class derivType) {
this.tracker = tracker;
this.reactivateThreshold = reactivateThreshold;
this.derivType = derivType;
int pyramidScaling[] = tracker.getTrackerKlt().pyramidScaling;
pyramid = FactoryPyramid.discreteGaussian(pyramidScaling,-1,2,true, ImageType.single(imageType));
gradient = FactoryDerivative.sobel(imageType, derivType);
reset();
}
@Override
public void reset() {
tracker.reset();
previousSpawn = 0;
detected = false;
}
@Override
public void process(I image) {
detected = false;
// update the image pyramid
pyramid.process(image);
if( derivX == null ) {
derivX = PyramidOps.declareOutput(pyramid, derivType);
derivY = PyramidOps.declareOutput(pyramid, derivType);
}
PyramidOps.gradient(pyramid, gradient, derivX, derivY);
// pass in filtered inputs
tracker.updateTracks(image, pyramid, derivX, derivY);
int numActive = tracker.getPureKlt().size() + tracker.getReactivated().size();
if( previousSpawn-numActive > reactivateThreshold) {
detected = true;
tracker.associateAllToDetected();
previousSpawn = tracker.getPureKlt().size() + tracker.getReactivated().size();
}
// Update the PointTrack state for KLT tracks
for( CombinedTrack t : tracker.getPureKlt() ) {
((PointTrack)t.getCookie()).set(t);
}
for( CombinedTrack t : tracker.getReactivated() ) {
((PointTrack)t.getCookie()).set(t);
}
}
@Override
public void spawnTracks() {
if( !detected ) {
tracker.associateAllToDetected();
}
tracker.spawnTracksFromDetected();
List> spawned = tracker.getSpawned();
for( CombinedTrack t : spawned ) {
PointTrack p = t.getCookie();
if( p == null ) {
p = new PointTrack();
t.setCookie(p);
}
p.set(t);
p.setDescription(t);
p.featureId = t.featureId;
}
previousSpawn = tracker.getPureKlt().size() + tracker.getReactivated().size();
}
@Override
public void dropAllTracks() {
tracker.dropAllTracks();
}
@Override
public boolean dropTrack(PointTrack track) {
if( tracker.dropTrack((CombinedTrack) track.getDescription()) ) {
// make sure if the user drops a lot of tracks that doesn't force a constant respawn
previousSpawn--;
return true;
} else {
return false;
}
}
@Override
public List getAllTracks(List list) {
if( list == null ) {
list = new ArrayList<>();
}
addToList(tracker.getReactivated(),list);
addToList(tracker.getPureKlt(),list);
addToList(tracker.getDormant(),list);
return list;
}
@Override
public List getActiveTracks(List list) {
if( list == null ) {
list = new ArrayList<>();
}
addToList(tracker.getReactivated(),list);
addToList(tracker.getPureKlt(),list);
return list;
}
@Override
public List getInactiveTracks(List list) {
if( list == null ) {
list = new ArrayList<>();
}
addToList(tracker.getDormant(),list);
return list;
}
@Override
public List getDroppedTracks(List list) {
if( list == null ) {
list = new ArrayList<>();
}
// it never drops tracks
return list;
}
@Override
public List getNewTracks(List list) {
if( list == null ) {
list = new ArrayList<>();
}
addToList(tracker.getSpawned(),list);
return list;
}
private void addToList( List> in , List out ) {
for( int i = 0; i < in.size(); i++ ) {
out.add( (PointTrack)in.get(i).getCookie() );
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy