use of boofcv.alg.tracker.klt.KltTrackFault in project BoofCV by lessthanoptimal.
the class DenseOpticalFlowKlt method process.
public void process(ImagePyramid<I> prev, D[] prevDerivX, D[] prevDerivY, ImagePyramid<I> curr, ImageFlow output) {
this.width = output.width;
this.height = output.height;
// initialize and set the score for each pixel to be very high
int N = width * height;
if (scores.length < N)
scores = new float[N];
Arrays.fill(scores, 0, N, Float.MAX_VALUE);
for (int i = 0; i < N; i++) {
output.data[i].markInvalid();
}
for (int y = 0; y < output.height; y++) {
for (int x = 0; x < output.width; x++) {
tracker.setImage(prev, prevDerivX, prevDerivY);
feature.setPosition(x, y);
if (tracker.setDescription(feature)) {
// derivX and derivY are not used, but can't be null for setImage()
tracker.setImage(curr);
KltTrackFault fault = tracker.track(feature);
if (fault == KltTrackFault.SUCCESS) {
float score = tracker.getError();
// bias the result to prefer the central template
scores[y * output.width + x] = score * MAGIC_ADJUSTMENT;
output.get(x, y).set(feature.x - x, feature.y - y);
// see if this flow should be assigned to any of its neighbors
checkNeighbors(x, y, score, feature.x - x, feature.y - y, output);
}
}
}
}
}
use of boofcv.alg.tracker.klt.KltTrackFault in project BoofCV by lessthanoptimal.
the class PointTrackerTwoPassKltPyramid method performSecondPass.
@Override
public void performSecondPass() {
candidateDrop.clear();
active.clear();
for (int i = 0; i < originalActive.size(); i++) {
PyramidKltFeature t = originalActive.get(i);
KltTrackFault ret = tracker.track(t);
boolean success = false;
if (ret == KltTrackFault.SUCCESS) {
// discard a track if its center drifts outside the image.
if (BoofMiscOps.checkInside(input, t.x, t.y)) {
active.add(t);
PointTrack p = t.getCookie();
p.set(t.x, t.y);
success = true;
}
}
if (!success) {
candidateDrop.add(t);
}
}
}
use of boofcv.alg.tracker.klt.KltTrackFault in project BoofCV by lessthanoptimal.
the class SparseFlowObjectTracker method trackFeatures.
/**
* Tracks features from the previous image into the current image. Tracks are created inside the specified
* region in a grid pattern.
*/
private void trackFeatures(Image input, RectangleRotate_F64 region) {
pairs.reset();
currentImage.process(input);
for (int i = 0; i < currentImage.getNumLayers(); i++) {
Image layer = currentImage.getLayer(i);
gradient.process(layer, currentDerivX[i], currentDerivY[i]);
}
// convert to float to avoid excessive conversions from double to float
float cx = (float) region.cx;
float cy = (float) region.cy;
float height = (float) (region.height);
float width = (float) (region.width);
float c = (float) Math.cos(region.theta);
float s = (float) Math.sin(region.theta);
float p = 1.0f / (config.numberOfSamples - 1);
for (int i = 0; i < config.numberOfSamples; i++) {
float y = (p * i - 0.5f) * height;
for (int j = 0; j < config.numberOfSamples; j++) {
float x = (p * j - 0.5f) * width;
float xx = cx + x * c - y * s;
float yy = cy + x * s + y * c;
// track in the forward direction
track.x = xx;
track.y = yy;
klt.setImage(previousImage, previousDerivX, previousDerivY);
if (!klt.setDescription(track)) {
continue;
}
klt.setImage(currentImage, currentDerivX, currentDerivY);
KltTrackFault fault = klt.track(track);
if (fault != KltTrackFault.SUCCESS) {
continue;
}
float xc = track.x;
float yc = track.y;
// validate by tracking backwards
if (!klt.setDescription(track)) {
continue;
}
klt.setImage(previousImage, previousDerivX, previousDerivY);
fault = klt.track(track);
if (fault != KltTrackFault.SUCCESS) {
continue;
}
float error = UtilPoint2D_F32.distanceSq(track.x, track.y, xx, yy);
if (error > maximumErrorFB) {
continue;
}
// create a list of the observations
AssociatedPair a = pairs.grow();
a.p1.x = xx;
a.p1.y = yy;
a.p2.x = xc;
a.p2.y = yc;
}
}
}
use of boofcv.alg.tracker.klt.KltTrackFault in project BoofCV by lessthanoptimal.
the class PointTrackerTwoPassKltPyramid method process.
@Override
public void process(I image) {
this.input = image;
finishedTracking = false;
spawned.clear();
dropped.clear();
// update image pyramids
basePyramid.process(image);
declareOutput();
PyramidOps.gradient(basePyramid, gradient, derivX, derivY);
// setup active list
originalActive.clear();
originalActive.addAll(active);
// track features
candidateDrop.clear();
active.clear();
tracker.setImage(basePyramid, derivX, derivY);
for (int i = 0; i < originalActive.size(); i++) {
PyramidKltFeature t = originalActive.get(i);
KltTrackFault ret = tracker.track(t);
boolean success = false;
if (ret == KltTrackFault.SUCCESS) {
// discard a track if its center drifts outside the image.
if (BoofMiscOps.checkInside(input, t.x, t.y)) {
active.add(t);
PointTrack p = t.getCookie();
p.set(t.x, t.y);
success = true;
}
}
if (!success) {
candidateDrop.add(t);
}
}
}
use of boofcv.alg.tracker.klt.KltTrackFault in project BoofCV by lessthanoptimal.
the class TldRegionTracker method trackFeature.
/**
* Tracks KLT features in forward/reverse direction and the tracking error metrics
*/
protected boolean trackFeature() {
pairs.reset();
// total number of tracks which contribute to FB error
int numTracksFB = 0;
// tracks which are not dropped
int numTracksRemaining = 0;
for (int i = 0; i < tracks.length; i++) {
Track t = tracks[i];
if (!t.active)
continue;
float prevX = t.klt.x;
float prevY = t.klt.y;
// track in forwards direction
tracker.setImage(currentImage, currentDerivX, currentDerivY);
KltTrackFault result = tracker.track(t.klt);
if (result != KltTrackFault.SUCCESS) {
t.active = false;
continue;
}
float currX = t.klt.x;
float currY = t.klt.y;
// track in reverse direction
tracker.setDescription(t.klt);
tracker.setImage(previousImage, previousDerivX, previousDerivY);
result = tracker.track(t.klt);
if (result != KltTrackFault.SUCCESS) {
t.active = false;
continue;
}
// compute forward-backwards error
double errorForwardBackwards = UtilPoint2D_F32.distanceSq(prevX, prevY, t.klt.x, t.klt.y);
// put into lists for computing the median error
errorsFB[numTracksFB++] = errorForwardBackwards;
// discard if error is too large
if (errorForwardBackwards > maxErrorFB) {
t.active = false;
continue;
}
// create data structure used for group motion estimation
AssociatedPair p = pairs.grow();
p.p1.set(prevX, prevY);
p.p2.set(currX, currY);
numTracksRemaining++;
}
// if the forward-backwards error is too large, give up
double medianFB = QuickSelect.select(errorsFB, numTracksFB / 2, numTracksFB);
if (medianFB > maxErrorFB || numTracksRemaining < 4)
return false;
return true;
}
Aggregations