@Test public void elementMultConjB() { InterleavedF64 a = new InterleavedF64(width, height, 2); InterleavedF64 b = new InterleavedF64(width, height, 2); InterleavedF64 c = new InterleavedF64(width, height, 2); ImageMiscOps.fillUniform(a, rand, -10, 10); ImageMiscOps.fillUniform(b, rand, -10, 10); ImageMiscOps.fillUniform(c, rand, -10, 10); CirculantTracker.elementMultConjB(a, b, c); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { Complex64F aa = new Complex64F(a.getBand(x, y, 0), a.getBand(x, y, 1)); Complex64F bb = new Complex64F(b.getBand(x, y, 0), b.getBand(x, y, 1)); Complex64F cc = new Complex64F(); ComplexMath64F.conj(bb, bb); ComplexMath64F.mult(aa, bb, cc); double foundReal = c.getBand(x, y, 0); double foundImg = c.getBand(x, y, 1); assertEquals(cc.real, foundReal, 1e-4); assertEquals(cc.imaginary, foundImg, 1e-4); } } }
@Test public void computeAlphas() { InterleavedF64 yf = new InterleavedF64(width, height, 2); InterleavedF64 kf = new InterleavedF64(width, height, 2); InterleavedF64 alphaf = new InterleavedF64(width, height, 2); ImageMiscOps.fillUniform(yf, rand, -10, 10); ImageMiscOps.fillUniform(kf, rand, -10, 10); ImageMiscOps.fillUniform(alphaf, rand, -10, 10); float lambda = 0.01f; CirculantTracker.computeAlphas(yf, kf, lambda, alphaf); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { Complex64F a = new Complex64F(yf.getBand(x, y, 0), yf.getBand(x, y, 1)); Complex64F b = new Complex64F(kf.getBand(x, y, 0) + lambda, kf.getBand(x, y, 1)); Complex64F c = new Complex64F(); ComplexMath64F.div(a, b, c); double foundReal = alphaf.getBand(x, y, 0); double foundImg = alphaf.getBand(x, y, 1); assertEquals(c.real, foundReal, 1e-4); assertEquals(c.imaginary, foundImg, 1e-4); } } }
private void setTargetLocation(int x, int y) { ImageMiscOps.fillUniform(image, rand, 0, 1); ImageMiscOps.fillRectangle(image, 100, cornerX, cornerY, 20, 20); pyramid.process(image); for (int i = 0; i < pyramid.getNumLayers(); i++) { GradientSobel.process( pyramid.getLayer(i), derivX[i], derivY[i], new ImageBorder1D_F32(BorderIndex1D_Extend.class)); } }
public BenchmarkConvolveNormalizeEdge() { imgInt8 = new ImageUInt8(imgWidth, imgHeight); imgInt16 = new ImageSInt16(imgWidth, imgHeight); out_I32 = new ImageSInt32(imgWidth, imgHeight); out_I16 = new ImageSInt16(imgWidth, imgHeight); out_I8 = new ImageUInt8(imgWidth, imgHeight); imgFloat32 = new ImageFloat32(imgWidth, imgHeight); out_F32 = new ImageFloat32(imgWidth, imgHeight); Random rand = new Random(234234); ImageMiscOps.fillUniform(imgInt8, rand, 0, 100); ImageMiscOps.fillUniform(imgInt16, rand, 0, 200); ImageMiscOps.fillUniform(imgFloat32, rand, 0, 200); }
protected void checkMotion(double tranX, double tranY, double rot) { ImageUInt8 frame0 = new ImageUInt8(320, 240); ImageUInt8 frame1 = new ImageUInt8(320, 240); ImageMiscOps.fillUniform(frame0, rand, 0, 256); double c = Math.cos(rot); double s = Math.sin(rot); DistortImageOps.affine(frame0, frame1, TypeInterpolate.BILINEAR, c, -s, s, c, tranX, tranY); SfotConfig config = new SfotConfig(); ImageGradient<ImageUInt8, ImageSInt16> gradient = FactoryDerivative.sobel(ImageUInt8.class, ImageSInt16.class); SparseFlowObjectTracker<ImageUInt8, ImageSInt16> alg = new SparseFlowObjectTracker<ImageUInt8, ImageSInt16>( config, ImageUInt8.class, ImageSInt16.class, gradient); RectangleRotate_F64 region0 = new RectangleRotate_F64(120, 140, 30, 40, 0.1); RectangleRotate_F64 region1 = new RectangleRotate_F64(); alg.init(frame0, region0); assertTrue(alg.update(frame1, region1)); double expectedX = c * region0.cx - s * region0.cy + tranX; double expectedY = s * region0.cx + c * region0.cy + tranY; double expectedYaw = UtilAngle.bound(region0.theta + rot); assertEquals(expectedX, region1.cx, 0.5); assertEquals(expectedY, region1.cy, 0.5); assertEquals(expectedYaw, region1.theta, 0.01); }
@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); }
/** * Creates a random image and looks for corners in it. Sees if the naive and fast algorithm * produce exactly the same results. */ @Test public void compareToNaive() { GrayU8 img = new GrayU8(width, height); ImageMiscOps.fillUniform(img, new Random(0xfeed), 0, 100); GrayS16 derivX = new GrayS16(img.getWidth(), img.getHeight()); GrayS16 derivY = new GrayS16(img.getWidth(), img.getHeight()); GradientSobel.process(img, derivX, derivY, new ImageBorder1D_S32(BorderIndex1D_Extend.class)); BoofTesting.checkSubImage(this, "compareToNaive", true, derivX, derivY); }
@Override public void renderTarget(ImageFloat32 original, List<CalibrationObservation> solutions) { ImageMiscOps.fill(original, 255); int numRows = config.numRows * 2 - 1; int numCols = config.numCols * 2 - 1; int square = original.getWidth() / (Math.max(numRows, numCols) + 4); int targetWidth = square * numCols; int targetHeight = square * numRows; int x0 = (original.width - targetWidth) / 2; int y0 = (original.height - targetHeight) / 2; for (int i = 0; i < numRows; i += 2) { int y = y0 + i * square; for (int j = 0; j < numCols; j += 2) { int x = x0 + j * square; ImageMiscOps.fillRectangle(original, 0, x, y, square, square); } } int pointsRow = numRows + 1; int pointsCol = numCols + 1; CalibrationObservation set = new CalibrationObservation(); int gridIndex = 0; for (int i = 0; i < pointsRow; i++) { for (int j = 0; j < pointsCol; j++, gridIndex++) { double y = y0 + i * square; double x = x0 + j * square; set.add(new Point2D_F64(x, y), gridIndex); } } solutions.add(set); }
@Test public void imageDotProduct() { ImageFloat64 a = new ImageFloat64(width, height); ImageMiscOps.fillUniform(a, rand, 0, 10); double total = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { total += a.get(x, y) * a.get(x, y); } } double found = CirculantTracker.imageDotProduct(a); assertEquals(total, found, 1e-8); }
protected void performThresholding(float threshLow, float threshHigh, ImageUInt8 output) { if (hysteresisPts != null) { hysteresisPts.process(suppressed, direction, threshLow, threshHigh); // if there is an output image write the contour to it if (output != null) { ImageMiscOps.fill(output, 0); for (EdgeContour e : hysteresisPts.getContours()) { for (EdgeSegment s : e.segments) for (Point2D_I32 p : s.points) output.unsafe_set(p.x, p.y, 1); } } } else { hysteresisMark.process(suppressed, direction, threshLow, threshHigh, output); } }
@Test public void compareToConvolve_I8() throws NoSuchMethodException { CompareDerivativeToConvolution validator = new CompareDerivativeToConvolution(); validator.setTarget( HessianThree_Standard.class.getMethod( "process", ImageUInt8.class, ImageSInt16.class, ImageSInt16.class, ImageSInt16.class)); validator.setKernel(0, HessianThree.kernelXXYY_I32, true); validator.setKernel(1, HessianThree.kernelXXYY_I32, false); validator.setKernel(2, HessianThree.kernelCross_I32); ImageUInt8 input = new ImageUInt8(width, height); ImageMiscOps.fillUniform(input, rand, 0, 10); ImageSInt16 derivXX = new ImageSInt16(width, height); ImageSInt16 derivYY = new ImageSInt16(width, height); ImageSInt16 derivXY = new ImageSInt16(width, height); validator.compare(false, input, derivXX, derivYY, derivXY); }
@Test public void compareToConvolve_F32() throws NoSuchMethodException { CompareDerivativeToConvolution validator = new CompareDerivativeToConvolution(); validator.setTarget( GradientPrewitt.class.getMethod( "process", ImageFloat32.class, ImageFloat32.class, ImageFloat32.class, ImageBorder_F32.class)); validator.setKernel(0, GradientPrewitt.kernelDerivX_F32); validator.setKernel(1, GradientPrewitt.kernelDerivY_F32); ImageFloat32 input = new ImageFloat32(width, height); ImageMiscOps.fillUniform(input, rand, 0, 10); ImageFloat32 derivX = new ImageFloat32(width, height); ImageFloat32 derivY = new ImageFloat32(width, height); validator.compare(input, derivX, derivY); }
@Test public void checkRender() { // Easier to make up a plane in this direction Se3_F64 cameraToPlane = new Se3_F64(); ConvertRotation3D_F64.eulerToMatrix( EulerType.XYZ, UtilAngle.degreeToRadian(0), 0, 0, cameraToPlane.getR()); cameraToPlane.getT().set(0, -5, 0); Se3_F64 planeToCamera = cameraToPlane.invert(null); CreateSyntheticOverheadViewMS<ImageFloat32> alg = new CreateSyntheticOverheadViewMS<ImageFloat32>( TypeInterpolate.BILINEAR, 3, ImageFloat32.class); alg.configure(param, planeToCamera, centerX, centerY, cellSize, overheadW, overheadH); MultiSpectral<ImageFloat32> input = new MultiSpectral<ImageFloat32>(ImageFloat32.class, width, height, 3); for (int i = 0; i < 3; i++) ImageMiscOps.fill(input.getBand(i), 10 + i); MultiSpectral<ImageFloat32> output = new MultiSpectral<ImageFloat32>(ImageFloat32.class, overheadW, overheadH, 3); alg.process(input, output); for (int i = 0; i < 3; i++) { ImageFloat32 o = output.getBand(i); // check parts that shouldn't be in view assertEquals(0, o.get(0, 300), 1e-8); assertEquals(0, o.get(5, 0), 1e-8); assertEquals(0, o.get(5, 599), 1e-8); // check areas that should be in view assertEquals(10 + i, o.get(499, 300), 1e-8); } }
@Test public void basic() { ImageUInt8 image = new ImageUInt8(400, 500); int value = 200; ImageMiscOps.fillRectangle(image, value, 20, 30, 40, 40); PolygonEdgeScore<ImageUInt8> alg = new PolygonEdgeScore<ImageUInt8>(2, 2, 10, value * 0.9, ImageUInt8.class); Polygon2D_F64 polygon = new Polygon2D_F64(4); UtilPolygons2D_F64.convert(new Rectangle2D_F64(20, 30, 60, 70), polygon); alg.setImage(image); assertTrue(alg.validate(polygon)); assertEquals(value, alg.getAverageEdgeIntensity(), 1e-8); UtilPolygons2D_F64.convert(new Rectangle2D_F64(24, 30, 60, 70), polygon); // test a negative case assertFalse(alg.validate(polygon)); assertEquals(value * 3.0 / 4.0, alg.getAverageEdgeIntensity(), 1e-8); }