use of boofcv.abst.feature.tracker.PointTrack in project MAVSlam by ecmnet.
the class MAVOdomPixelDepthPnP method performSecondPass.
private boolean performSecondPass(List<PointTrack> active, List<Point2D3D> obs) {
Se3_F64 keyToCurr = motionEstimator.getModelParameters();
Point3D_F64 cameraPt = new Point3D_F64();
Point2D_F64 predicted = new Point2D_F64();
// predict where each track should be given the just estimated motion
List<PointTrack> all = tracker.getAllTracks(null);
for (PointTrack t : all) {
Point2D3D p = t.getCookie();
SePointOps_F64.transform(keyToCurr, p.location, cameraPt);
normToPixel.compute(cameraPt.x / cameraPt.z, cameraPt.y / cameraPt.z, predicted);
tracker.setHint(predicted.x, predicted.y, t);
}
// redo tracking with the additional information
tracker.performSecondPass();
active.clear();
obs.clear();
tracker.getActiveTracks(active);
for (PointTrack t : active) {
Point2D3D p = t.getCookie();
pixelToNorm.compute(t.x, t.y, p.observation);
obs.add(p);
}
return motionEstimator.process(obs);
}
use of boofcv.abst.feature.tracker.PointTrack in project MAVSlam by ecmnet.
the class MAVOdomPixelDepthPnP method changePoseToReference.
/**
* Updates the relative position of all points so that the current frame is
* the reference frame. Mathematically this is not needed, but should help
* keep numbers from getting too large.
*/
private void changePoseToReference() {
Se3_F64 keyToCurr = currToKey.invert(null);
List<PointTrack> all = tracker.getAllTracks(null);
for (PointTrack t : all) {
Point2D3DTrack p = t.getCookie();
SePointOps_F64.transform(keyToCurr, p.location, p.location);
}
concatMotion();
}
use of boofcv.abst.feature.tracker.PointTrack in project narchy by automenta.
the class WebcamTrack method main.
public static void main(String[] args) {
// tune the tracker for the image size and visual appearance
ConfigGeneralDetector configDetector = new ConfigGeneralDetector(-1, 8, 1);
PkltConfig configKlt = new PkltConfig(3, new int[] { 1, 2, 4, 8 });
PointTracker<ImageFloat32> tracker = FactoryPointTracker.klt(configKlt, configDetector, ImageFloat32.class, null);
// Open a webcam at a resolution close to 640x480
Webcam webcam = UtilWebcamCapture.openDefault(640, 480);
// Create the panel used to display the image and
ImagePanel gui = new ImagePanel();
gui.setPreferredSize(webcam.getViewSize());
ShowImages.showWindow(gui, "KLT Tracker");
int minimumTracks = 100;
while (true) {
BufferedImage image = webcam.getImage();
ImageFloat32 gray = ConvertBufferedImage.convertFrom(image, (ImageFloat32) null);
tracker.process(gray);
List<PointTrack> tracks = tracker.getActiveTracks(null);
// Spawn tracks if there are too few
if (tracks.size() < minimumTracks) {
tracker.spawnTracks();
tracks = tracker.getActiveTracks(null);
minimumTracks = tracks.size() / 2;
}
// Draw the tracks
Graphics2D g2 = image.createGraphics();
for (PointTrack t : tracks) {
VisualizeFeatures.drawPoint(g2, (int) t.x, (int) t.y, Color.RED);
}
gui.setBufferedImageSafe(image);
}
}
use of boofcv.abst.feature.tracker.PointTrack in project BoofCV by lessthanoptimal.
the class VisOdomDualTrackPnP method addNewTracks.
/**
* Spawns tracks in each image and associates features together.
*/
private void addNewTracks() {
trackerLeft.spawnTracks();
trackerRight.spawnTracks();
List<PointTrack> newLeft = trackerLeft.getNewTracks(null);
List<PointTrack> newRight = trackerRight.getNewTracks(null);
// get a list of new tracks and their descriptions
addNewToList(inputLeft, newLeft, pointsLeft, descLeft);
addNewToList(inputRight, newRight, pointsRight, descRight);
// associate using L2R
assocL2R.setSource(pointsLeft, descLeft);
assocL2R.setDestination(pointsRight, descRight);
assocL2R.associate();
FastQueue<AssociatedIndex> matches = assocL2R.getMatches();
// storage for the triangulated location in the camera frame
Point3D_F64 cameraP3 = new Point3D_F64();
for (int i = 0; i < matches.size; i++) {
AssociatedIndex m = matches.get(i);
PointTrack trackL = newLeft.get(m.src);
PointTrack trackR = newRight.get(m.dst);
// declare additional track information stored in each track. Tracks can be recycled so it
// might not always need to be declared
LeftTrackInfo infoLeft = trackL.getCookie();
if (infoLeft == null)
trackL.cookie = infoLeft = new LeftTrackInfo();
RightTrackInfo infoRight = trackR.getCookie();
if (infoRight == null)
trackR.cookie = infoRight = new RightTrackInfo();
Stereo2D3D p2d3d = infoLeft.location;
// convert pixel observations into normalized image coordinates
leftImageToNorm.compute(trackL.x, trackL.y, p2d3d.leftObs);
rightImageToNorm.compute(trackR.x, trackR.y, p2d3d.rightObs);
// triangulate 3D coordinate in the current camera frame
if (triangulate.triangulate(p2d3d.leftObs, p2d3d.rightObs, leftToRight, cameraP3)) {
// put the track into the current keyframe coordinate system
SePointOps_F64.transform(currToKey, cameraP3, p2d3d.location);
// save a reference to the matching track in the right camera frame
infoLeft.right = trackR;
infoLeft.lastConsistent = infoLeft.lastInlier = tick;
infoRight.left = trackL;
} else {
// triangulation failed, drop track
trackerLeft.dropTrack(trackL);
// TODO need way to mark right tracks which are unassociated after this loop
throw new RuntimeException("This special case needs to be handled!");
}
}
// drop tracks that were not associated
GrowQueue_I32 unassignedRight = assocL2R.getUnassociatedDestination();
for (int i = 0; i < unassignedRight.size; i++) {
int index = unassignedRight.get(i);
// System.out.println(" unassigned right "+newRight.get(index).x+" "+newRight.get(index).y);
trackerRight.dropTrack(newRight.get(index));
}
GrowQueue_I32 unassignedLeft = assocL2R.getUnassociatedSource();
for (int i = 0; i < unassignedLeft.size; i++) {
int index = unassignedLeft.get(i);
trackerLeft.dropTrack(newLeft.get(index));
}
// System.out.println("Total left "+trackerLeft.getAllTracks(null).size()+" right "+trackerRight.getAllTracks(null).size());
// System.out.println("Associated: "+matches.size+" new left "+newLeft.size()+" new right "+newRight.size());
// System.out.println("New Tracks: Total: Left "+trackerLeft.getAllTracks(null).size()+" right "+
// trackerRight.getAllTracks(null).size());
// List<PointTrack> temp = trackerLeft.getActiveTracks(null);
// for( PointTrack t : temp ) {
// if( t.cookie == null )
// System.out.println("BUG!");
// }
// temp = trackerRight.getActiveTracks(null);
// for( PointTrack t : temp ) {
// if( t.cookie == null )
// System.out.println("BUG!");
// }
}
use of boofcv.abst.feature.tracker.PointTrack in project BoofCV by lessthanoptimal.
the class VisOdomDualTrackPnP method selectCandidateTracks.
/**
* Searches for tracks which are active and meet the epipolar constraints
*/
private void selectCandidateTracks() {
// mark tracks in right frame that are active
List<PointTrack> activeRight = trackerRight.getActiveTracks(null);
for (PointTrack t : activeRight) {
RightTrackInfo info = t.getCookie();
info.lastActiveList = tick;
}
int mutualActive = 0;
List<PointTrack> activeLeft = trackerLeft.getActiveTracks(null);
candidates.clear();
for (PointTrack left : activeLeft) {
LeftTrackInfo info = left.getCookie();
// if( info == null || info.right == null ) {
// System.out.println("Oh Crap");
// }
// for each active left track, see if its right track has been marked as active
RightTrackInfo infoRight = info.right.getCookie();
if (infoRight.lastActiveList != tick) {
continue;
}
// check epipolar constraint and see if it is still valid
if (stereoCheck.checkPixel(left, info.right)) {
info.lastConsistent = tick;
candidates.add(left);
}
mutualActive++;
}
// System.out.println("Active Tracks: Left "+trackerLeft.getActiveTracks(null).size()+" right "+
// trackerRight.getActiveTracks(null).size());
// System.out.println("All Tracks: Left "+trackerLeft.getAllTracks(null).size()+" right "+
// trackerRight.getAllTracks(null).size());
// System.out.println("Candidates = "+candidates.size()+" mutual active = "+mutualActive);
}
Aggregations