@Test public void performLearning() { float interp_factor = 0.075f; ImageFloat32 a = new ImageFloat32(20, 25); ImageFloat32 b = new ImageFloat32(20, 25); ImageMiscOps.fill(a, 100); ImageMiscOps.fill(b, 200); CirculantTracker<ImageFloat32> alg = new CirculantTracker<ImageFloat32>(1f / 16, 0.2, 1e-2, 0.075, 1.0, 64, 255, interp); alg.initialize(a, 0, 0, 20, 25); // copy its internal value ImageFloat64 templateC = new ImageFloat64(alg.template.width, alg.template.height); templateC.setTo(alg.template); // give it two images alg.performLearning(b); // make sure the images aren't full of zero assertTrue(Math.abs(ImageStatistics.sum(templateC)) > 0.1); assertTrue(Math.abs(ImageStatistics.sum(alg.template)) > 0.1); int numNotSame = 0; // the result should be an average of the two for (int i = 0; i < a.data.length; i++) { if (Math.abs(a.data[i] - alg.templateNew.data[i]) > 1e-4) numNotSame++; // should be more like the original one than the new one double expected = templateC.data[i] * (1 - interp_factor) + interp_factor * alg.templateNew.data[i]; double found = alg.template.data[i]; assertEquals(expected, found, 1e-4); } // make sure it is actually different assertTrue(numNotSame > 100); }
@Test public void basicTrackingCheck() { ImageFloat32 a = new ImageFloat32(30, 35); ImageFloat32 b = new ImageFloat32(30, 35); // randomize input image and move it GImageMiscOps.fillUniform(a, rand, 0, 200); GImageMiscOps.fillUniform(b, rand, 0, 200); CirculantTracker<ImageFloat32> alg = new CirculantTracker<ImageFloat32>(1f / 16, 0.2, 1e-2, 0.075, 1.0, 64, 255, interp); alg.initialize(a, 5, 6, 20, 25); shiftCopy(2, 4, a, b); alg.performTracking(b); double tolerance = 1; Rectangle2D_F32 r = alg.getTargetLocation(); assertEquals(5 + 2, r.x0, tolerance); assertEquals(6 + 4, r.y0, tolerance); }
/** * Check a few simple motions. It seems to be accurate to within 1 pixel. Considering alphas seems * to be the issue */ @Test public void updateTrackLocation() { ImageFloat32 a = new ImageFloat32(100, 100); ImageFloat32 b = new ImageFloat32(100, 100); // randomize input image and move it GImageMiscOps.fillUniform(a, rand, 0, 200); GImageMiscOps.fillUniform(b, rand, 0, 200); shiftCopy(0, 0, a, b); CirculantTracker<ImageFloat32> alg = new CirculantTracker<ImageFloat32>(1f / 16, 0.2, 1e-2, 0.075, 1.0, 64, 255, interp); alg.initialize(a, 5, 6, 20, 25); alg.updateTrackLocation(b); // only pixel level precision. float tolerance = 1f; // No motion motion Rectangle2D_F32 r = alg.getTargetLocation(); assertEquals(5, r.x0, tolerance); assertEquals(6, r.y0, tolerance); // check estimated motion GImageMiscOps.fillUniform(b, rand, 0, 200); shiftCopy(-3, 2, a, b); alg.updateTrackLocation(b); r = alg.getTargetLocation(); assertEquals(5 - 3, r.x0, tolerance); assertEquals(6 + 2, r.y0, tolerance); // try out of bounds case GImageMiscOps.fillUniform(b, rand, 0, 200); shiftCopy(-6, 0, a, b); alg.updateTrackLocation(b); assertEquals(5 - 6, r.x0, tolerance); assertEquals(6, r.y0, tolerance); }
public void dense_gauss_kernel(int offX, int offY) { ImageFloat64 region = new ImageFloat64(32, 32); ImageFloat64 target = new ImageFloat64(32, 32); ImageFloat64 k = new ImageFloat64(32, 32); CirculantTracker<ImageFloat32> alg = new CirculantTracker<ImageFloat32>(1f / 16, 0.2, 1e-2, 0.075, 1.0, 32, 255, interp); alg.initialize(new ImageFloat32(32, 32), 0, 0, 32, 32); // create a shape inside the image GImageMiscOps.fillRectangle(region, 200, 10, 15, 5, 7); // copy a shifted portion of the region shiftCopy(offX, offY, region, target); // process and see if the peak is where it should be alg.dense_gauss_kernel(0.2f, region, target, k); int maxX = -1, maxY = -1; double maxValue = -1; for (int y = 0; y < k.height; y++) { for (int x = 0; x < k.width; x++) { if (k.get(x, y) > maxValue) { maxValue = k.get(x, y); maxX = x; maxY = y; } } } int expectedX = k.width / 2 - offX; int expectedY = k.height / 2 - offY; assertEquals(expectedX, maxX); assertEquals(expectedY, maxY); }