content: package org.opencv.test.core;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  
  import org.opencv.core.Core;
  import org.opencv.core.Core.MinMaxLocResult;
  import org.opencv.core.CvException;
  import org.opencv.core.CvType;
  import org.opencv.core.Mat;
  import org.opencv.core.MatOfDouble;
  import org.opencv.core.MatOfInt;
  import org.opencv.core.MatOfPoint;
  import org.opencv.core.Point;
  import org.opencv.core.Rect;
  import org.opencv.core.RotatedRect;
  import org.opencv.core.Scalar;
  import org.opencv.core.Size;
  import org.opencv.core.TermCriteria;
  import org.opencv.test.OpenCVTestCase;
  import org.opencv.imgproc.Imgproc;
  
  public class CoreTest extends OpenCVTestCase {
  
      public void testAbsdiff() {
          Core.absdiff(gray128, gray255, dst);
  
          assertMatEqual(gray127, dst);
      }
  
      public void testAddMatMatMat() {
          Core.add(gray128, gray128, dst);
  
          assertMatEqual(gray255, dst);
      }
  
      public void testAddMatMatMatMatInt() {
          Core.add(gray0, gray1, dst, gray1, CvType.CV_32F);
  
          assertEquals(CvType.CV_32F, dst.depth());
          assertMatEqual(gray1_32f, dst, EPS);
      }
  
      public void testAddWeightedMatDoubleMatDoubleDoubleMat() {
          Core.addWeighted(gray1, 120.0, gray127, 1.0, 10.0, dst);
  
          assertMatEqual(gray255, dst);
      }
  
      public void testAddWeightedMatDoubleMatDoubleDoubleMatInt() {
          Core.addWeighted(gray1, 126.0, gray127, 1.0, 2.0, dst, CvType.CV_32F);
  
          assertEquals(CvType.CV_32F, dst.depth());
          assertMatEqual(gray255_32f, dst, EPS);
      }
  
      public void testBitwise_andMatMatMat() {
          Core.bitwise_and(gray127, gray3, dst);
  
          assertMatEqual(gray3, dst);
      }
  
      public void testBitwise_andMatMatMatMat() {
          Core.bitwise_and(gray3, gray1, dst, gray255);
  
          assertMatEqual(gray1, dst);
      }
  
      public void testBitwise_notMatMat() {
          Core.bitwise_not(gray255, dst);
  
          assertMatEqual(gray0, dst);
      }
  
      public void testBitwise_notMatMatMat() {
          Core.bitwise_not(gray0, dst, gray1);
  
          assertMatEqual(gray255, dst);
      }
  
      public void testBitwise_orMatMatMat() {
          Core.bitwise_or(gray1, gray2, dst);
  
          assertMatEqual(gray3, dst);
      }
  
      public void testBitwise_orMatMatMatMat() {
          Core.bitwise_or(gray127, gray3, dst, gray255);
  
          assertMatEqual(gray127, dst);
      }
  
      public void testBitwise_xorMatMatMat() {
          Core.bitwise_xor(gray3, gray2, dst);
  
          assertMatEqual(gray1, dst);
      }
  
      public void testBitwise_xorMatMatMatMat() {
          Core.bitwise_or(gray127, gray128, dst, gray255);
  
          assertMatEqual(gray255, dst);
      }
  
      public void testCalcCovarMatrixMatMatMatInt() {
          Mat covar = new Mat(matSize, matSize, CvType.CV_64FC1);
          Mat mean = new Mat(1, matSize, CvType.CV_64FC1);
  
          Core.calcCovarMatrix(gray0_32f, covar, mean, Core.COVAR_ROWS | Core.COVAR_NORMAL);
  
          assertMatEqual(gray0_64f, covar, EPS);
          assertMatEqual(gray0_64f_1d, mean, EPS);
      }
  
      public void testCalcCovarMatrixMatMatMatIntInt() {
          Mat covar = new Mat(matSize, matSize, CvType.CV_32F);
          Mat mean = new Mat(1, matSize, CvType.CV_32F);
  
          Core.calcCovarMatrix(gray0_32f, covar, mean, Core.COVAR_ROWS | Core.COVAR_NORMAL, CvType.CV_32F);
  
          assertMatEqual(gray0_32f, covar, EPS);
          assertMatEqual(gray0_32f_1d, mean, EPS);
      }
  
      public void testCartToPolarMatMatMatMat() {
          Mat x = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, 3.0, 6.0, 5, 0);
              }
          };
          Mat y = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, 4.0, 8.0, 12.0);
              }
          };
          Mat dst_angle = new Mat();
  
          Core.cartToPolar(x, y, dst, dst_angle);
  
          Mat expected_magnitude = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, 5.0, 10.0, 13.0);
              }
          };
          Mat expected_angle = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, atan2rad(4,3), atan2rad(8,6), atan2rad(12,5));
              }
          };
          assertMatEqual(expected_magnitude, dst, EPS);
          assertMatEqual(expected_angle, dst_angle, EPS);
      }
  
      public void testCartToPolarMatMatMatMatBoolean() {
          Mat x = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, 3.0, 6.0, 5, 0);
              }
          };
          Mat y = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, 4.0, 8.0, 12.0);
              }
          };
          Mat dst_angle = new Mat();
  
          Core.cartToPolar(x, y, dst, dst_angle, true);
  
          Mat expected_magnitude = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, 5.0, 10.0, 13.0);
              }
          };
          Mat expected_angle = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, atan2deg(4,3), atan2deg(8,6), atan2deg(12,5));
              }
          };
          assertMatEqual(expected_magnitude, dst, EPS);
          assertMatEqual(expected_angle, dst_angle, EPS * 180/Math.PI);
      }
  
  
      public void testCheckRangeMat() {
          Mat outOfRange = new Mat(2, 2, CvType.CV_64F);
          outOfRange.put(0, 0, Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 0);
  
          assertTrue(Core.checkRange(grayRnd_32f));
          assertTrue(Core.checkRange(new Mat()));
          assertFalse(Core.checkRange(outOfRange));
      }
  
  
      public void testCheckRangeMatBooleanPointDoubleDouble() {
          Mat inRange = new Mat(2, 3, CvType.CV_64F) {
              {
                  put(0, 0, 14, 48, 76, 33, 5, 99);
              }
          };
  
          assertTrue(Core.checkRange(inRange, true, 5, 100));
  
          Mat outOfRange = new Mat(2, 3, CvType.CV_64F) {
              {
                  put(0, 0, -4, 0, 6, 33, 4, 109);
              }
          };
  
          assertFalse(Core.checkRange(outOfRange, true, 5, 100));
      }
  
      public void testCompare() {
          Core.compare(gray0, gray0, dst, Core.CMP_EQ);
  
          assertMatEqual(dst, gray255);
  
          Core.compare(gray0, gray1, dst, Core.CMP_EQ);
  
          assertMatEqual(dst, gray0);
  
          grayRnd.put(0, 0, 0, 0);
  
          Core.compare(gray0, grayRnd, dst, Core.CMP_GE);
  
          int expected = (int) (grayRnd.total() - Core.countNonZero(grayRnd));
          assertEquals(expected, Core.countNonZero(dst));
      }
  
      public void testCompleteSymmMat() {
          Core.completeSymm(grayRnd_32f);
  
          assertMatEqual(grayRnd_32f, grayRnd_32f.t(), EPS);
      }
  
      public void testCompleteSymmMatBoolean() {
          Mat grayRnd_32f2 = grayRnd_32f.clone();
  
          Core.completeSymm(grayRnd_32f, true);
  
          assertMatEqual(grayRnd_32f, grayRnd_32f.t(), EPS);
          Core.completeSymm(grayRnd_32f2, false);
          assertMatNotEqual(grayRnd_32f2, grayRnd_32f, EPS);
      }
  
      public void testConvertScaleAbsMatMat() {
          Core.convertScaleAbs(gray0, dst);
  
          assertMatEqual(gray0, dst, EPS);
  
          Core.convertScaleAbs(gray_16u_256, dst);
  
          assertMatEqual(gray255, dst, EPS);
      }
  
      public void testConvertScaleAbsMatMatDoubleDouble() {
          Core.convertScaleAbs(gray_16u_256, dst, 2, -513);
  
          assertMatEqual(gray1, dst);
      }
  
      public void testCountNonZero() {
          assertEquals(0, Core.countNonZero(gray0));
  
          gray0.put(0, 0, 255);
          gray0.put(gray0.rows() - 1, gray0.cols() - 1, 255);
  
          assertEquals(2, Core.countNonZero(gray0));
      }
  
      public void testCubeRoot() {
          float res = Core.cubeRoot(-27.0f);
  
          assertEquals(-3.0f, res);
      }
  
      public void testDctMatMat() {
          Mat in = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 135.22211, 50.811096, 102.27016, 207.6682);
              }
          };
          Mat dst1 = new Mat();
          Mat dst2 = new Mat();
  
          Core.dct(gray0_32f_1d, dst1);
          Core.dct(in, dst2);
  
          truth = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 247.98576, -61.252407, 94.904533, 14.013477);
              }
          };
          assertMatEqual(gray0_32f_1d, dst1, EPS);
          assertMatEqual(truth, dst2, EPS);
      }
  
      public void testDctMatMatInt() {
          Mat in = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 247.98576, -61.252407, 94.904533, 14.013477);
              }
          };
          Mat dst1 = new Mat();
          Mat dst2 = new Mat();
  
          Core.dct(gray0_32f_1d, dst1, Core.DCT_INVERSE);
          Core.dct(in, dst2, Core.DCT_INVERSE);
  
          truth = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 135.22211, 50.811096, 102.27016, 207.6682);
              }
          };
          assertMatEqual(gray0_32f_1d, dst1, EPS);
          assertMatEqual(truth, dst2, EPS);
      }
  
      public void testDeterminant() {
          Mat mat = new Mat(2, 2, CvType.CV_32F) {
              {
                  put(0, 0, 4.0);
                  put(0, 1, 2.0);
                  put(1, 0, 4.0);
                  put(1, 1, 4.0);
              }
          };
  
          double det = Core.determinant(mat);
  
          assertEquals(8.0, det);
      }
  
      public void testDftMatMat() {
          Core.dft(gray0_32f_1d, dst);
  
          assertMatEqual(gray0_32f_1d, dst, EPS);
      }
  
      public void testDftMatMatIntInt() {
          Mat src1 = new Mat(2, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1, 2, 3, 4);
                  put(1, 0, 1, 1, 1, 1);
              }
          };
          Mat src2 = new Mat(2, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1, 2, 3, 4);
                  put(1, 0, 0, 0, 0, 0);
              }
          };
          Mat dst1 = new Mat();
          Mat dst2 = new Mat();
  
          Core.dft(src1, dst1, Core.DFT_REAL_OUTPUT, 1);
          Core.dft(src2, dst2, Core.DFT_REAL_OUTPUT, 0);
  
          assertMatEqual(dst2, dst1, EPS);
      }
  
      public void testDivideDoubleMatMat() {
          Core.divide(4.0, gray2, dst);
  
          assertMatEqual(gray2, dst);
  
          Core.divide(4.0, gray0, dst);
  
          assertMatEqual(gray0, dst);
      }
  
      public void testDivideDoubleMatMatInt() {
          Core.divide(9.0, gray3, dst, CvType.CV_32F);
  
          assertMatEqual(gray3_32f, dst, EPS);
      }
  
      public void testDivideMatMatMat() {
          Core.divide(gray9, gray3, dst);
  
          assertMatEqual(gray3, dst);
      }
  
      public void testDivideMatMatMatDouble() {
          Core.divide(gray1, gray2, dst, 6.0);
  
          assertMatEqual(gray3, dst);
      }
  
      public void testDivideMatMatMatDoubleInt() {
          Core.divide(gray1, gray2, dst, 6.0, CvType.CV_32F);
  
          assertMatEqual(gray3_32f, dst, EPS);
      }
  
      public void testEigen() {
          Mat src = new Mat(3, 3, CvType.CV_32FC1) {
              {
                  put(0, 0, 2, 0, 0);
                  put(1, 0, 0, 6, 0);
                  put(2, 0, 0, 0, 4);
              }
          };
          Mat eigenVals = new Mat();
          Mat eigenVecs = new Mat();
  
          Core.eigen(src, eigenVals, eigenVecs);
  
          Mat expectedEigenVals = new Mat(3, 1, CvType.CV_32FC1) {
              {
                  put(0, 0, 6, 4, 2);
              }
          };
          assertMatEqual(eigenVals, expectedEigenVals, EPS);
  
          // check by definition
          double eps = 1e-3;
          for(int i = 0; i < 3; i++)
          {
              Mat vec = eigenVecs.row(i).t();
              Mat lhs = new Mat(3, 1, CvType.CV_32FC1);
              Core.gemm(src, vec, 1.0, new Mat(), 1.0, lhs);
              Mat rhs = new Mat(3, 1, CvType.CV_32FC1);
              Core.gemm(vec, eigenVals.row(i), 1.0, new Mat(), 1.0, rhs);
              assertMatEqual(lhs, rhs, eps);
          }
      }
  
      public void testExp() {
          Core.exp(gray0_32f, dst);
  
          assertMatEqual(gray1_32f, dst, EPS);
      }
  
      public void testExtractChannel() {
          Core.extractChannel(rgba128, dst, 0);
  
          assertMatEqual(gray128, dst);
      }
  
      public void testFastAtan2() {
          double eps = 0.3;
  
          float res = Core.fastAtan2(50, 50);
  
          assertEquals(45, res, eps);
  
          float res2 = Core.fastAtan2(80, 20);
  
          assertEquals(Math.atan2(80, 20) * 180 / Math.PI, res2, eps);
      }
  
      public void testFillConvexPolyMatListOfPointScalar() {
          MatOfPoint polyline = new MatOfPoint(new Point[]{new Point(1, 1), new Point(5, 0), new Point(6, 8), new Point(0, 9)});
  
          Imgproc.fillConvexPoly(gray0, polyline, new Scalar(150));
  
          assertTrue(0 < Core.countNonZero(gray0));
          assertTrue(gray0.total() > Core.countNonZero(gray0));
      }
  
      public void testFillConvexPolyMatListOfPointScalarIntInt() {
          MatOfPoint polyline1 = new MatOfPoint(new Point(2, 1), new Point(5, 1), new Point(5, 7), new Point(2, 7));
          MatOfPoint polyline2 = new MatOfPoint(new Point(4, 2), new Point(10, 2), new Point(10, 14), new Point(4, 14));
  
          // current implementation of fixed-point version of fillConvexPoly
          // requires image to be at least 2-pixel wider in each direction than
          // contour
          Imgproc.fillConvexPoly(gray0, polyline1, colorWhite, Imgproc.LINE_8, 0);
  
          assertTrue(0 < Core.countNonZero(gray0));
          assertTrue(gray0.total() > Core.countNonZero(gray0));
  
          Imgproc.fillConvexPoly(gray0, polyline2, colorBlack, Imgproc.LINE_8, 1);
  
          assertEquals("see http://code.opencv.org/issues/1284", 0, Core.countNonZero(gray0));
      }
  
      public void testFillPolyMatListOfListOfPointScalar() {
          int matSize = 10;
          Mat gray0 = Mat.zeros(matSize, matSize, CvType.CV_8U);
          MatOfPoint polyline = new MatOfPoint(new Point(1, 4), new Point(1, 8), new Point(4, 1), new Point(7, 8), new Point(7, 4));
          List<MatOfPoint> polylines = new ArrayList<MatOfPoint>();
          polylines.add(polyline);
  
          Imgproc.fillPoly(gray0, polylines, new Scalar(1));
  
          final byte[] truth = new byte[] {
                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                  0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
                  0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
                  0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
                  0, 1, 1, 1, 1, 1, 1, 1, 0, 0,
                  0, 1, 1, 0, 0, 0, 1, 1, 0, 0,
                  0, 1, 1, 0, 0, 0, 1, 1, 0, 0,
                  0, 1, 0, 0, 0, 0, 0, 1, 0, 0,
                  0, 1, 0, 0, 0, 0, 0, 1, 0, 0,
                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  
          assertMatEqual(new Mat(gray0.size(), CvType.CV_8U) {
              {
                  put(0, 0, truth);
              }
          }, gray0);
      }
  
      public void testFillPolyMatListOfListOfPointScalarIntIntPoint() {
          MatOfPoint polyline1 = new MatOfPoint(new Point(1, 4), new Point(1, 8), new Point(4, 1), new Point(7, 8), new Point(7, 4));
          MatOfPoint polyline2 = new MatOfPoint(new Point(0, 3), new Point(0, 7), new Point(3, 0), new Point(6, 7), new Point(6, 3));
  
          List<MatOfPoint> polylines1 = new ArrayList<MatOfPoint>();
          polylines1.add(polyline1);
  
          List<MatOfPoint> polylines2 = new ArrayList<MatOfPoint>();
          polylines2.add(polyline2);
  
          Imgproc.fillPoly(gray0, polylines1, new Scalar(1), Imgproc.LINE_8, 0, new Point(0, 0));
  
          assertTrue(0 < Core.countNonZero(gray0));
  
          Imgproc.fillPoly(gray0, polylines2, new Scalar(0), Imgproc.LINE_8, 0, new Point(1, 1));
  
          assertEquals(0, Core.countNonZero(gray0));
      }
  
      public void testFlip() {
          Mat src = new Mat(2, 2, CvType.CV_32F) {
              {
                  put(0, 0, 1.0);
                  put(0, 1, 2.0);
                  put(1, 0, 3.0);
                  put(1, 1, 4.0);
              }
          };
          Mat dst1 = new Mat();
          Mat dst2 = new Mat();
  
          Core.flip(src, dst1, 0);
          Core.flip(src, dst2, 1);
  
          Mat dst_f1 = new Mat(2, 2, CvType.CV_32F) {
              {
                  put(0, 0, 3.0);
                  put(0, 1, 4.0);
                  put(1, 0, 1.0);
                  put(1, 1, 2.0);
              }
          };
          Mat dst_f2 = new Mat(2, 2, CvType.CV_32F) {
              {
                  put(0, 0, 2.0);
                  put(0, 1, 1.0);
                  put(1, 0, 4.0);
                  put(1, 1, 3.0);
              }
          };
          assertMatEqual(dst_f1, dst1, EPS);
          assertMatEqual(dst_f2, dst2, EPS);
      }
  
      public void testGemmMatMatDoubleMatDoubleMat() {
          Mat m1 = new Mat(2, 2, CvType.CV_32FC1) {
              {
                  put(0, 0, 1.0, 0.0);
                  put(1, 0, 1.0, 0.0);
              }
          };
          Mat m2 = new Mat(2, 2, CvType.CV_32FC1) {
              {
                  put(0, 0, 1.0, 0.0);
                  put(1, 0, 1.0, 0.0);
              }
          };
          Mat dmatrix = new Mat(2, 2, CvType.CV_32FC1) {
              {
                  put(0, 0, 0.001, 0.001);
                  put(1, 0, 0.001, 0.001);
              }
          };
  
          Core.gemm(m1, m2, 1.0, dmatrix, 1.0, dst);
  
          Mat expected = new Mat(2, 2, CvType.CV_32FC1) {
              {
                  put(0, 0, 1.001, 0.001);
                  put(1, 0, 1.001, 0.001);
              }
          };
          assertMatEqual(expected, dst, EPS);
      }
  
      public void testGemmMatMatDoubleMatDoubleMatInt() {
          Mat m1 = new Mat(2, 2, CvType.CV_32FC1) {
              {
                  put(0, 0, 1.0, 0.0);
                  put(1, 0, 1.0, 0.0);
              }
          };
          Mat m2 = new Mat(2, 2, CvType.CV_32FC1) {
              {
                  put(0, 0, 1.0, 0.0);
                  put(1, 0, 1.0, 0.0);
              }
          };
          Mat dmatrix = new Mat(2, 2, CvType.CV_32FC1) {
              {
                  put(0, 0, 0.001, 0.001);
                  put(1, 0, 0.001, 0.001);
              }
          };
  
          Core.gemm(m1, m2, 1.0, dmatrix, 1.0, dst, Core.GEMM_1_T);
  
          Mat expected = new Mat(2, 2, CvType.CV_32FC1) {
              {
                  put(0, 0, 2.001, 0.001);
                  put(1, 0, 0.001, 0.001);
              }
          };
          assertMatEqual(expected, dst, EPS);
      }
  
      public void testGetCPUTickCount() {
          long cpuCountStart = 0, actualTickCount;
  
          cpuCountStart = Core.getCPUTickCount();
          Core.sumElems(gray255);
          actualTickCount = Core.getCPUTickCount();
  
          long expectedTickCount = actualTickCount - cpuCountStart;
          assertTrue(expectedTickCount > 0);
      }
  
      public void testGetNumberOfCPUs() {
          int cpus = Core.getNumberOfCPUs();
  
          assertTrue(Runtime.getRuntime().availableProcessors() <= cpus);
      }
  
      public void testGetOptimalDFTSize() {
          assertEquals(1, Core.getOptimalDFTSize(0));
          assertEquals(135, Core.getOptimalDFTSize(133));
          assertEquals(15, Core.getOptimalDFTSize(13));
      }
  
      public void testGetTickCount() {
          long startCount, endCount, count;
  
          startCount = Core.getTickCount();
          Core.divide(gray2, gray1, dst);
          endCount = Core.getTickCount();
  
          count = endCount - startCount;
          assertTrue(count > 0);
      }
  
      public void testGetTickFrequency() {
          double freq1 = Core.getTickFrequency();
          Core.divide(gray2, gray1, dst);
          double freq2 = Core.getTickFrequency();
  
          assertTrue(0 < freq1);
          assertEquals(freq1, freq2);
      }
  
      public void testHconcat() {
          List<Mat> mats = Arrays.asList(Mat.eye(3, 3, CvType.CV_8U), Mat.zeros(3, 2, CvType.CV_8U));
  
          Core.hconcat(mats, dst);
  
          assertMatEqual(Mat.eye(3, 5, CvType.CV_8U), dst);
      }
  
      public void testIdctMatMat() {
          Mat in = new Mat(1, 8, CvType.CV_32F) {
              {
                  put(0, 0, 1.0, 2.0, 1.0, 0.0, 1.0, 2.0, 3.0, 1.0);
              }
          };
  
          Core.idct(in, dst);
  
          truth = new Mat(1, 8, CvType.CV_32F) {
              {
                  put(0, 0, 3.3769724, -1.6215782, 2.3608727, 0.20730907, -0.86502546, 0.028082132, -0.7673766, 0.10917115);
              }
          };
          assertMatEqual(truth, dst, EPS);
      }
  
      public void testIdctMatMatInt() {
          Mat in = new Mat(2, 8, CvType.CV_32F) {
              {
                  put(0, 0, 1.0, 2.0, 1.0, 0.0, 1.0, 2.0, 3.0, 1.0);
                  put(1, 0, 1.0, 2.0, 1.0, 0.0, 1.0, 2.0, 3.0, 1.0);
              }
          };
  
          Core.idct(in, dst, Core.DCT_ROWS);
  
          truth = new Mat(2, 8, CvType.CV_32F) {
              {
                  put(0, 0, 3.3769724, -1.6215782, 2.3608727, 0.20730907, -0.86502546, 0.028082132, -0.7673766, 0.10917115);
                  put(1, 0, 3.3769724, -1.6215782, 2.3608727, 0.20730907, -0.86502546, 0.028082132, -0.7673766, 0.10917115);
              }
          };
          assertMatEqual(truth, dst, EPS);
      }
  
      public void testIdftMatMat() {
          Mat in = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1.0, 2.0, 3.0, 4.0);
              }
          };
  
          Core.idft(in, dst);
  
          truth = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 9, -9, 1, 3);
              }
          };
          assertMatEqual(truth, dst, EPS);
      }
  
      public void testIdftMatMatIntInt() {
          Mat in = new Mat(2, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1.0, 2.0, 3.0, 4.0);
                  put(1, 0, 1.0, 2.0, 3.0, 4.0);
              }
          };
          Mat dst = new Mat();
  
          Core.idft(in, dst, Core.DFT_REAL_OUTPUT, 1);
  
          truth = new Mat(2, 4, CvType.CV_32F) {
              {
                  put(0, 0, 18, -18, 2, 6);
                  put(1, 0, 0, 0, 0, 0);
              }
          };
          assertMatEqual(truth, dst, EPS);
      }
  
      public void testInRange() {
          gray0.put(1, 1, 100, 150, 200);
  
          Core.inRange(gray0, new Scalar(120), new Scalar(160), dst);
  
          byte vals[] = new byte[3];
          dst.get(1, 1, vals);
  
          assertEquals(0, vals[0]);
          assertEquals(-1, vals[1]);
          assertEquals(0, vals[2]);
          assertEquals(1, Core.countNonZero(dst));
      }
  
      public void testInsertChannel() {
          Core.insertChannel(gray0, rgba128, 0);
          Core.insertChannel(gray0, rgba128, 1);
          Core.insertChannel(gray0, rgba128, 2);
          Core.insertChannel(gray0, rgba128, 3);
  
          assertMatEqual(rgba0, rgba128);
      }
  
      public void testInvertMatMat() {
          Mat src = new Mat(2, 2, CvType.CV_32F) {
              {
                  put(0, 0, 1.0);
                  put(0, 1, 2.0);
                  put(1, 0, 1.5);
                  put(1, 1, 4.0);
              }
          };
  
          Core.invert(src, dst);
  
          truth = new Mat(2, 2, CvType.CV_32F) {
              {
                  put(0, 0, 4.0);
                  put(0, 1, -2.0);
                  put(1, 0, -1.5);
                  put(1, 1, 1.0);
              }
          };
          assertMatEqual(truth, dst, EPS);
      }
  
      public void testInvertMatMatInt() {
          Mat src = Mat.eye(3, 3, CvType.CV_32FC1);
          src.put(0, 2, 1);
  
          double cond = Core.invert(src, dst, Core.DECOMP_SVD);
  
          truth = Mat.eye(3, 3, CvType.CV_32FC1);
          truth.put(0, 2, -1);
          assertMatEqual(truth, dst, EPS);
          assertEquals(0.3819660544395447, cond, EPS);
      }
  
      public void testKmeansMatIntMatTermCriteriaIntInt() {
          Mat data = new Mat(4, 5, CvType.CV_32FC1) {
              {
                  put(0, 0, 1, 2, 3, 4, 5);
                  put(1, 0, 2, 3, 4, 5, 6);
                  put(2, 0, 5, 4, 3, 2, 1);
                  put(3, 0, 6, 5, 4, 3, 2);
              }
          };
          TermCriteria criteria = new TermCriteria(TermCriteria.EPS, 0, EPS);
          Mat labels = new Mat();
  
          Core.kmeans(data, 2, labels, criteria, 1, Core.KMEANS_PP_CENTERS);
  
          int[] first_center = new int[1];
          labels.get(0, 0, first_center);
          final int c1 = first_center[0];
          Mat expected_labels = new Mat(4, 1, CvType.CV_32S) {
              {
                  put(0, 0, c1, c1, 1 - c1, 1 - c1);
              }
          };
          assertMatEqual(expected_labels, labels);
      }
  
      public void testKmeansMatIntMatTermCriteriaIntIntMat() {
          Mat data = new Mat(4, 5, CvType.CV_32FC1) {
              {
                  put(0, 0, 1, 2, 3, 4, 5);
                  put(1, 0, 2, 3, 4, 5, 6);
                  put(2, 0, 5, 4, 3, 2, 1);
                  put(3, 0, 6, 5, 4, 3, 2);
              }
          };
          TermCriteria criteria = new TermCriteria(TermCriteria.EPS, 0, EPS);
          Mat labels = new Mat();
          Mat centers = new Mat();
  
          Core.kmeans(data, 2, labels, criteria, 6, Core.KMEANS_RANDOM_CENTERS, centers);
  
          int[] first_center = new int[1];
          labels.get(0, 0, first_center);
          final int c1 = first_center[0];
          Mat expected_labels = new Mat(4, 1, CvType.CV_32S) {
              {
                  put(0, 0, c1, c1, 1 - c1, 1 - c1);
              }
          };
          Mat expected_centers = new Mat(2, 5, CvType.CV_32FC1) {
              {
                  put(c1, 0, 1.5, 2.5, 3.5, 4.5, 5.5);
                  put(1 - c1, 0, 5.5, 4.5, 3.5, 2.5, 1.5);
              }
          };
          assertMatEqual(expected_labels, labels);
          assertMatEqual(expected_centers, centers, EPS);
      }
  
      public void testLineMatPointPointScalar() {
          int nPoints = Math.min(gray0.cols(), gray0.rows());
          Point point1 = new Point(0, 0);
          Point point2 = new Point(nPoints, nPoints);
          Scalar color = new Scalar(255);
  
          Imgproc.line(gray0, point1, point2, color);
  
          assertTrue(nPoints == Core.countNonZero(gray0));
      }
  
      public void testLineMatPointPointScalarInt() {
          int nPoints = Math.min(gray0.cols(), gray0.rows());
          Point point1 = new Point(0, 0);
          Point point2 = new Point(nPoints, nPoints);
  
          Imgproc.line(gray0, point1, point2, colorWhite, 1);
  
          assertTrue(nPoints == Core.countNonZero(gray0));
      }
  
      public void testLineMatPointPointScalarIntIntInt() {
          int nPoints = Math.min(gray0.cols(), gray0.rows());
          Point point1 = new Point(3, 4);
          Point point2 = new Point(nPoints, nPoints);
          Point point1_4 = new Point(3 * 4, 4 * 4);
          Point point2_4 = new Point(nPoints * 4, nPoints * 4);
  
          Imgproc.line(gray0, point2, point1, colorWhite, 2, Imgproc.LINE_8, 0);
  
          assertFalse(0 == Core.countNonZero(gray0));
  
          Imgproc.line(gray0, point2_4, point1_4, colorBlack, 2, Imgproc.LINE_8, 2);
  
          assertEquals(0, Core.countNonZero(gray0));
      }
  
      public void testLog() {
          Mat in = new Mat(1, 4, CvType.CV_32FC1) {
              {
                  put(0, 0, 1.0, 10.0, 100.0, 1000.0);
              }
          };
  
          Core.log(in, dst);
  
          Mat expected = new Mat(1, 4, CvType.CV_32FC1) {
              {
                  put(0, 0, 0, 2.3025851, 4.6051702, 6.9077554);
              }
          };
          assertMatEqual(expected, dst, EPS);
      }
  
      public void testLUTMatMatMat() {
          Mat lut = new Mat(1, 256, CvType.CV_8UC1);
          lut.setTo(new Scalar(0));
  
          Core.LUT(grayRnd, lut, dst);
  
          assertMatEqual(gray0, dst);
  
          lut.setTo(new Scalar(255));
  
          Core.LUT(grayRnd, lut, dst);
  
          assertMatEqual(gray255, dst);
      }
  
      public void testMagnitude() {
          Mat x = new Mat(1, 4, CvType.CV_32F);
          Mat y = new Mat(1, 4, CvType.CV_32F);
          x.put(0, 0, 3.0, 5.0, 9.0, 6.0);
          y.put(0, 0, 4.0, 12.0, 40.0, 8.0);
  
          Core.magnitude(x, y, dst);
  
          Mat out = new Mat(1, 4, CvType.CV_32F);
          out.put(0, 0, 5.0, 13.0, 41.0, 10.0);
          assertMatEqual(out, dst, EPS);
  
          Core.magnitude(gray0_32f, gray255_32f, dst);
  
          assertMatEqual(gray255_32f, dst, EPS);
      }
  
      public void testMahalanobis() {
          Mat src = new Mat(matSize, matSize, CvType.CV_32F);
          Core.randu(src, -128, 128);
  
          Mat covar = new Mat(matSize, matSize, CvType.CV_32F);
          Mat mean = new Mat(1, matSize, CvType.CV_32F);
          Core.calcCovarMatrix(src, covar, mean, Core.COVAR_ROWS | Core.COVAR_NORMAL, CvType.CV_32F);
          covar = covar.inv();
  
          Mat line1 = src.row(0);
          Mat line2 = src.row(1);
  
          double d = Core.Mahalanobis(line1, line1, covar);
  
          assertEquals(0.0, d);
  
          d = Core.Mahalanobis(line1, line2, covar);
  
          assertTrue(d > 0.0);
      }
  
      public void testMax() {
          Core.max(gray0, gray255, dst);
  
          assertMatEqual(gray255, dst);
  
          Mat x = new Mat(1, 1, CvType.CV_32F);
          Mat y = new Mat(1, 1, CvType.CV_32F);
          x.put(0, 0, 23.0);
          y.put(0, 0, 4.0);
  
          Core.max(x, y, dst);
  
          Mat truth = new Mat(1, 1, CvType.CV_32F);
          truth.put(0, 0, 23.0);
          assertMatEqual(truth, dst, EPS);
      }
  
      public void testMeanMat() {
          Scalar mean = Core.mean(makeMask(gray128));
  
          assertScalarEqual(new Scalar(64), mean, EPS);
      }
  
      public void testMeanMatMat() {
          Mat mask1 = makeMask(gray1.clone());
          Mat mask2 = makeMask(gray0, 1);
  
          Scalar mean1 = Core.mean(grayRnd, mask1);
          Scalar mean2 = Core.mean(grayRnd, mask2);
          Scalar mean = Core.mean(grayRnd, gray1);
  
          assertScalarEqual(mean, new Scalar(0.5 * (mean1.val[0] + mean2.val[0])), EPS);
      }
  
      public void testMeanStdDevMatMatMat() {
          MatOfDouble mean   = new MatOfDouble();
          MatOfDouble stddev = new MatOfDouble();
  
          Core.meanStdDev(rgbLena, mean, stddev);
  
          double expectedMean[] = new double[]
              {105.3989906311035, 99.56269836425781, 179.7303047180176};
          double expectedDev[] = new double[]
              {33.74205485167219, 52.8734582803278, 49.01569488056406};
  
          assertArrayEquals(expectedMean, mean.toArray(), EPS);
          assertArrayEquals(expectedDev, stddev.toArray(), EPS);
      }
  
      public void testMeanStdDevMatMatMatMat() {
          Mat submat = grayRnd.submat(0, grayRnd.rows() / 2, 0, grayRnd.cols() / 2);
          submat.setTo(new Scalar(33));
          Mat mask = gray0.clone();
          submat = mask.submat(0, mask.rows() / 2, 0, mask.cols() / 2);
          submat.setTo(new Scalar(1));
          MatOfDouble mean   = new MatOfDouble();
          MatOfDouble stddev = new MatOfDouble();
  
          Core.meanStdDev(grayRnd, mean, stddev, mask);
  
          double expectedMean[] = new double[] {33d};
          double expectedDev[]  = new double[] {0d};
  
          assertArrayEquals(expectedMean, mean.toArray(), EPS);
          assertArrayEquals(expectedDev, stddev.toArray(), EPS);
      }
  
      public void testMerge() {
          Mat src1 = new Mat(2, 2, CvType.CV_32FC1, new Scalar(1));
          Mat src2 = new Mat(2, 2, CvType.CV_32FC1, new Scalar(2));
          Mat src3 = new Mat(2, 2, CvType.CV_32FC1, new Scalar(3));
          List<Mat> listMat = Arrays.asList(src1, src2, src3);
  
          Core.merge(listMat, dst);
  
          truth = new Mat(2, 2, CvType.CV_32FC3, new Scalar(1, 2, 3));
          assertMatEqual(truth, dst, EPS);
      }
  
      public void testMin() {
          Core.min(gray0, gray255, dst);
  
          assertMatEqual(gray0, dst);
      }
  
      public void testMinMaxLocMat() {
          double minVal = 1;
          double maxVal = 10;
          Point minLoc = new Point(gray3.cols() / 4, gray3.rows() / 2);
          Point maxLoc = new Point(gray3.cols() / 2, gray3.rows() / 4);
          gray3.put((int) minLoc.y, (int) minLoc.x, minVal);
          gray3.put((int) maxLoc.y, (int) maxLoc.x, maxVal);
  
          Core.MinMaxLocResult mmres = Core.minMaxLoc(gray3);
  
          assertEquals(minVal, mmres.minVal);
          assertEquals(maxVal, mmres.maxVal);
          assertPointEquals(minLoc, mmres.minLoc, EPS);
          assertPointEquals(maxLoc, mmres.maxLoc, EPS);
      }
  
      public void testMinMaxLocMatMat() {
          Mat src = new Mat(4, 4, CvType.CV_8U) {
              {
                  put(0, 0, 2, 4, 27, 3);
                  put(1, 0, 0, 8, 7, 130);
                  put(2, 0, 13, 4, 13, 4);
                  put(3, 0, 6, 4, 2, 13);
              }
          };
          Mat mask = new Mat(4, 4, CvType.CV_8U, new Scalar(0));
          mask.submat(1, 3, 1, 4).setTo(new Scalar(1));
  
          MinMaxLocResult res = Core.minMaxLoc(src, mask);
  
          assertEquals(4.0, res.minVal);
          assertEquals(130.0, res.maxVal);
          assertPointEquals(new Point(1, 2), res.minLoc, EPS);
          assertPointEquals(new Point(3, 1), res.maxLoc, EPS);
      }
  
      public void testMixChannels() {
          rgba0.setTo(new Scalar(10, 20, 30, 40));
          List<Mat> src = Arrays.asList(rgba0);
          List<Mat> dst = Arrays.asList(gray3, gray2, gray1, gray0, getMat(CvType.CV_8UC3, 0, 0, 0));
          MatOfInt fromTo = new MatOfInt(
                  3, 0,
                  3, 1,
                  2, 2,
                  0, 3,
                  2, 4,
                  1, 5,
                  0, 6
          );
  
          Core.mixChannels(src, dst, fromTo);
  
          assertMatEqual(getMat(CvType.CV_8U, 40), dst.get(0));
          assertMatEqual(getMat(CvType.CV_8U, 40), dst.get(1));
          assertMatEqual(getMat(CvType.CV_8U, 30), dst.get(2));
          assertMatEqual(getMat(CvType.CV_8U, 10), dst.get(3));
          assertMatEqual(getMat(CvType.CV_8UC3, 30, 20, 10), dst.get(4));
      }
  
      public void testMulSpectrumsMatMatMatInt() {
          Mat src1 = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1.0, 2.0, 3.0, 4.0);
              }
          };
          Mat src2 = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1.0, 2.0, 3.0, 4.0);
              }
          };
  
          Core.mulSpectrums(src1, src2, dst, Core.DFT_ROWS);
  
          Mat expected = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1, -5, 12, 16);
              }
          };
          assertMatEqual(expected, dst, EPS);
      }
  
      public void testMulSpectrumsMatMatMatIntBoolean() {
          Mat src1 = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1.0, 2.0, 3.0, 4.0);
              }
          };
          Mat src2 = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1.0, 2.0, 3.0, 4.0);
              }
          };
  
          Core.mulSpectrums(src1, src2, dst, Core.DFT_ROWS, true);
  
          Mat expected = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1, 13, 0, 16);
              }
          };
          assertMatEqual(expected, dst, EPS);
      }
  
      public void testMultiplyMatMatMat() {
          Core.multiply(gray0, gray255, dst);
  
          assertMatEqual(gray0, dst);
      }
  
      public void testMultiplyMatMatMatDouble() {
          Core.multiply(gray1, gray1, dst, 2.0);
  
          assertMatEqual(gray2, dst);
  
      }
  
      public void testMultiplyMatMatMatDoubleInt() {
          Core.multiply(gray1, gray2, dst, 1.5, CvType.CV_32F);
  
          assertMatEqual(gray3_32f, dst, EPS);
      }
  
      public void testMulTransposedMatMatBoolean() {
          Core.mulTransposed(grayE_32f, dst, true);
  
          assertMatEqual(grayE_32f, dst, EPS);
      }
  
      public void testMulTransposedMatMatBooleanMatDouble() {
          Core.mulTransposed(grayE_32f, dst, true, gray0_32f, 2);
  
          truth = gray0_32f;
          truth.diag().setTo(new Scalar(2));
          assertMatEqual(truth, dst, EPS);
      }
  
      public void testMulTransposedMatMatBooleanMatDoubleInt() {
          Mat a = getMat(CvType.CV_32F, 1);
  
          Core.mulTransposed(a, dst, true, gray0_32f, 3, CvType.CV_64F);
  
          assertMatEqual(getMat(CvType.CV_64F, 3 * a.rows()), dst, EPS);
      }
  
      public void testNormalizeMatMat() {
          Mat m = gray0.clone();
          m.diag().setTo(new Scalar(2));
  
          Core.normalize(m, dst);
  
          assertMatEqual(gray0, dst);
      }
  
      public void testNormalizeMatMatDoubleDoubleInt() {
          Mat src = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1.0, 2.0, 3.0, 4.0);
              }
          };
  
          Core.normalize(src, dst, 1.0, 2.0, Core.NORM_INF);
  
          Mat expected = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 0.25, 0.5, 0.75, 1);
              }
          };
          assertMatEqual(expected, dst, EPS);
      }
  
      public void testNormalizeMatMatDoubleDoubleIntInt() {
          Mat src = new Mat(1, 5, CvType.CV_32F) {
              {
                  put(0, 0, 0, 1, 2, 3, 4);
              }
          };
  
          Core.normalize(src, dst, 1, 2, Core.NORM_MINMAX, CvType.CV_64F);
  
          Mat expected = new Mat(1, 5, CvType.CV_64F) {
              {
                  put(0, 0, 1, 1.25, 1.5, 1.75, 2);
              }
          };
          assertMatEqual(expected, dst, EPS);
      }
  
      public void testNormalizeMatMatDoubleDoubleIntIntMat() {
          Mat src = new Mat(1, 5, CvType.CV_32F) {
              {
                  put(0, 0, 0, 1, 2, 3, 4);
              }
          };
          Mat mask = new Mat(1, 5, CvType.CV_8U) {
              {
                  put(0, 0, 1, 0, 0, 0, 1);
              }
          };
          dst = src.clone();
  
          Core.normalize(src, dst, 1, 2, Core.NORM_MINMAX, CvType.CV_32F, mask);
  
          Mat expected = new Mat(1, 5, CvType.CV_32F) {
              {
                  put(0, 0, 1, 1, 2, 3, 2);
              }
          };
          assertMatEqual(expected, dst, EPS);
      }
  
      public void testNormMat() {
          double n = Core.norm(gray1);
  
          assertEquals(10., n);
      }
  
      public void testNormMatInt() {
          double n = Core.norm(gray127, Core.NORM_INF);
  
          assertEquals(127., n);
      }
  
      public void testNormMatIntMat() {
          double n = Core.norm(gray3, Core.NORM_L1, gray0);
  
          assertEquals(0.0, n);
      }
  
      public void testNormMatMat() {
          double n = Core.norm(gray0, gray1);
  
          assertEquals(10.0, n);
      }
  
      public void testNormMatMatInt() {
          double n = Core.norm(gray127, gray1, Core.NORM_INF);
  
          assertEquals(126.0, n);
      }
  
      public void testNormMatMatIntMat() {
          double n = Core.norm(gray3, gray0, Core.NORM_L1, makeMask(gray0.clone(), 1));
  
          assertEquals(150.0, n);
      }
  
      public void testPCABackProject() {
          Mat mean = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 2, 4, 4, 8);
              }
          };
          Mat vectors = new Mat(1, 4, CvType.CV_32F, new Scalar(0)) {
              {
                  put(0, 0, 0.2, 0.4, 0.4, 0.8);
              }
          };
          Mat data = new Mat(3, 1, CvType.CV_32F) {
              {
                  put(0, 0, -5, 0, -10);
              }
          };
          Mat result = new Mat();
  
          Core.PCABackProject(data, mean, vectors, result);
  
          Mat truth = new Mat(3, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1, 2, 2, 4);
                  put(1, 0, 2, 4, 4, 8);
                  put(2, 0, 0, 0, 0, 0);
              }
          };
          assertMatEqual(truth, result, EPS);
      }
  
      public void testPCAComputeMatMatMat() {
          Mat data = new Mat(3, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1, 2, 2, 4);
                  put(1, 0, 2, 4, 4, 8);
                  put(2, 0, 3, 6, 6, 12);
              }
          };
          Mat mean = new Mat();
          Mat vectors = new Mat();
  
          Core.PCACompute(data, mean, vectors);
          //System.out.println(mean.dump());
          //System.out.println(vectors.dump());
          Mat mean_truth = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 2, 4, 4, 8);
              }
          };
          Mat vectors_truth = new Mat(3, 4, CvType.CV_32F, new Scalar(0)) {
              {
                  put(0, 0, 0.2, 0.4, 0.4, 0.8);
              }
          };
          assertMatEqual(mean_truth, mean, EPS);
  
          // eigenvectors are normalized (length = 1),
          // but direction is unknown (v and -v are both eigen vectors)
          // so this direct check doesn't work:
          // assertMatEqual(vectors_truth, vectors, EPS);
          for(int i = 0; i < 3; i++)
          {
              Mat vec0 = vectors_truth.row(i);
              Mat vec1 = vectors.row(i);
              Mat vec1_ = new Mat();
              Core.subtract(new Mat(1, 4, CvType.CV_32F, new Scalar(0)), vec1, vec1_);
              double scale1 = Core.norm(vec0, vec1);
              double scale2 = Core.norm(vec0, vec1_);
              assertTrue(Math.min(scale1, scale2) < EPS);
          }
      }
  
      public void testPCAComputeMatMatMatInt() {
          Mat data = new Mat(3, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1, 2, 2, 4);
                  put(1, 0, 2, 4, 4, 8);
                  put(2, 0, 3, 6, 6, 12);
              }
          };
          Mat mean = new Mat();
          Mat vectors = new Mat();
  
          Core.PCACompute(data, mean, vectors, 1);
  
          Mat mean_truth = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 2, 4, 4, 8);
              }
          };
          Mat vectors_truth = new Mat(1, 4, CvType.CV_32F, new Scalar(0)) {
              {
                  put(0, 0, 0.2, 0.4, 0.4, 0.8);
              }
          };
          assertMatEqual(mean_truth, mean, EPS);
          // eigenvectors are normalized (length = 1),
          // but direction is unknown (v and -v are both eigen vectors)
          // so this direct check doesn't work:
          // assertMatEqual(vectors_truth, vectors, EPS);
          for(int i = 0; i < 1; i++)
          {
              Mat vec0 = vectors_truth.row(i);
              Mat vec1 = vectors.row(i);
              Mat vec1_ = new Mat();
              Core.subtract(new Mat(1, 4, CvType.CV_32F, new Scalar(0)), vec1, vec1_);
              double scale1 = Core.norm(vec0, vec1);
              double scale2 = Core.norm(vec0, vec1_);
              assertTrue(Math.min(scale1, scale2) < EPS);
          }
      }
  
      public void testPCAProject() {
          Mat mean = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 2, 4, 4, 8);
              }
          };
          Mat vectors = new Mat(1, 4, CvType.CV_32F, new Scalar(0)) {
              {
                  put(0, 0, 0.2, 0.4, 0.4, 0.8);
              }
          };
          Mat data = new Mat(3, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1, 2, 2, 4);
                  put(1, 0, 2, 4, 4, 8);
                  put(2, 0, 0, 0, 0, 0);
              }
          };
          Mat result = new Mat();
  
          Core.PCAProject(data, mean, vectors, result);
  
          Mat truth = new Mat(3, 1, CvType.CV_32F) {
              {
                  put(0, 0, -5, 0, -10);
              }
          };
          assertMatEqual(truth, result, EPS);
      }
  
      public void testPerspectiveTransform() {
          Mat src = new Mat(matSize, matSize, CvType.CV_32FC2);
          Core.randu(src, 0, 256);
          Mat transformMatrix = Mat.eye(3, 3, CvType.CV_32F);
  
          Core.perspectiveTransform(src, dst, transformMatrix);
          assertMatEqual(src, dst, EPS);
      }
  
      public void testPerspectiveTransform3D() {
          Mat src = new Mat(matSize, matSize, CvType.CV_32FC3);
          Core.randu(src, 0, 256);
          Mat transformMatrix = Mat.eye(4, 4, CvType.CV_32F);
  
          Core.perspectiveTransform(src, dst, transformMatrix);
  
          assertMatEqual(src, dst, EPS);
      }
  
      private static double atan2deg(double y, double x)
      {
          double res = Math.atan2(y, x);
          if (res < 0)
              res = Math.PI * 2 + res;
          return res * 180 / Math.PI;
      }
  
      private static double atan2rad(double y, double x)
      {
          double res = Math.atan2(y, x);
          if (res < 0)
              res = Math.PI * 2 + res;
          return res;
      }
  
      public void testPhaseMatMatMat() {
          Mat x = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 10.0, 10.0, 20.0, 5.0);
              }
          };
          Mat y = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 20.0, 15.0, 20.0, 20.0);
              }
          };
          Mat gold = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, atan2rad(20, 10), atan2rad(15, 10), atan2rad(20, 20), atan2rad(20, 5));
              }
          };
  
          Core.phase(x, y, dst);
  
          assertMatEqual(gold, dst, EPS);
      }
  
      public void testPhaseMatMatMatBoolean() {
          Mat x = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 10.0, 10.0, 20.0, 5.0);
              }
          };
          Mat y = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 20.0, 15.0, 20.0, 20.0);
              }
          };
          Mat gold = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, atan2deg(20, 10), atan2deg(15, 10), atan2deg(20, 20), atan2deg(20, 5));
              }
          };
  
          Core.phase(x, y, dst, true);
  
          assertMatEqual(gold, dst, EPS * 180 / Math.PI);
      }
  
      public void testPolarToCartMatMatMatMat() {
          Mat magnitude = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, 5.0, 10.0, 13.0);
              }
          };
          Mat angle = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, 0.92729962, 0.92729962, 1.1759995);
              }
          };
          Mat xCoordinate = new Mat();
          Mat yCoordinate = new Mat();
  
          Core.polarToCart(magnitude, angle, xCoordinate, yCoordinate);
  
          Mat x = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, 3.0, 6.0, 5, 0);
              }
          };
          Mat y = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, 4.0, 8.0, 12.0);
              }
          };
          assertMatEqual(x, xCoordinate, EPS);
          assertMatEqual(y, yCoordinate, EPS);
      }
  
      public void testPolarToCartMatMatMatMatBoolean() {
          Mat magnitude = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, 5.0, 10.0, 13.0);
              }
          };
          Mat angle = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, 0.92729962, 0.92729962, 1.1759995);
              }
          };
          Mat xCoordinate = new Mat();
          Mat yCoordinate = new Mat();
  
          Core.polarToCart(magnitude, angle, xCoordinate, yCoordinate, true);
  
          Mat x = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, 4.9993458, 9.9986916, 12.997262);
              }
          };
          Mat y = new Mat(1, 3, CvType.CV_32F) {
              {
                  put(0, 0, 0.080918625, 0.16183725, 0.26680708);
              }
          };
          assertMatEqual(x, xCoordinate, EPS);
          assertMatEqual(y, yCoordinate, EPS);
      }
  
      public void testPow() {
          Core.pow(gray2, 7, dst);
  
          assertMatEqual(gray128, dst);
      }
  
      public void testRandn() {
          Core.randn(gray0, 100, 23);
  
          assertEquals(100., Core.mean(gray0).val[0], 23 / 2);
      }
  
      public void testRandShuffleMat() {
          Mat original = new Mat(1, 10, CvType.CV_32F) {
              {
                  put(0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
              }
          };
          Mat shuffled = original.clone();
  
          Core.randShuffle(shuffled);
  
          assertMatNotEqual(original, shuffled, EPS);
          Mat dst1 = new Mat();
          Mat dst2 = new Mat();
          Core.sort(original, dst1, Core.SORT_ASCENDING);
          Core.sort(shuffled, dst2, Core.SORT_ASCENDING);
          assertMatEqual(dst1, dst2, EPS);
      }
  
      public void testRandShuffleMatDouble() {
          Mat original = new Mat(1, 10, CvType.CV_32F) {
              {
                  put(0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
              }
          };
          Mat shuffled = original.clone();
  
          Core.randShuffle(shuffled, 10);
  
          assertMatNotEqual(original, shuffled, EPS);
          Mat dst1 = new Mat();
          Mat dst2 = new Mat();
          Core.sort(original, dst1, Core.SORT_ASCENDING);
          Core.sort(shuffled, dst2, Core.SORT_ASCENDING);
          assertMatEqual(dst1, dst2, EPS);
      }
  
      public void testRandu() {
          Core.randu(gray0, 3, 23);
          fail("Not yet implemented");
          //assertTrue(Core.checkRange(gray0, true, null, 3, 23));
      }
  
      public void testRectangleMatPointPointScalar() {
          Point bottomRight = new Point(gray0.cols() / 2, gray0.rows() / 2);
          Point topLeft = new Point(0, 0);
          Scalar color = new Scalar(128);
  
          Imgproc.rectangle(gray0, bottomRight, topLeft, color);
  
          assertTrue(0 != Core.countNonZero(gray0));
      }
  
      public void testRectangleMatPointPointScalarInt() {
          Point bottomRight = new Point(gray0.cols(), gray0.rows());
          Point topLeft = new Point(0, 0);
          Scalar color = new Scalar(128);
  
          Imgproc.rectangle(gray0, bottomRight, topLeft, color, 2);
          Imgproc.rectangle(gray0, bottomRight, topLeft, colorBlack);
  
          assertTrue(0 != Core.countNonZero(gray0));
      }
  
      public void testRectangleMatPointPointScalarIntInt() {
          Point bottomRight = new Point(gray0.cols() / 2, gray0.rows() / 2);
          Point topLeft = new Point(0, 0);
          Scalar color = new Scalar(128);
  
          Imgproc.rectangle(gray0, bottomRight, topLeft, color, 2, Imgproc.LINE_AA, 0);
          Imgproc.rectangle(gray0, bottomRight, topLeft, colorBlack, 2, Imgproc.LINE_4, 0);
  
          assertTrue(0 != Core.countNonZero(gray0));
      }
  
      public void testRectangleMatPointPointScalarIntIntInt() {
          Point bottomRight1 = new Point(gray0.cols(), gray0.rows());
          Point bottomRight2 = new Point(gray0.cols() / 2, gray0.rows() / 2);
          Point topLeft = new Point(0, 0);
          Scalar color = new Scalar(128);
  
          Imgproc.rectangle(gray0, bottomRight1, topLeft, color, 2, Imgproc.LINE_8, 1);
  
          assertTrue(0 != Core.countNonZero(gray0));
  
          Imgproc.rectangle(gray0, bottomRight2, topLeft, colorBlack, 2, Imgproc.LINE_8, 0);
  
          assertEquals(0, Core.countNonZero(gray0));
      }
  
      public void testReduceMatMatIntInt() {
          Mat src = new Mat(2, 2, CvType.CV_32F) {
              {
                  put(0, 0, 1, 0);
                  put(1, 0, 3, 0);
              }
          };
  
          Core.reduce(src, dst, 0, Core.REDUCE_AVG);
  
          Mat out = new Mat(1, 2, CvType.CV_32F) {
              {
                  put(0, 0, 2, 0);
              }
          };
          assertMatEqual(out, dst, EPS);
      }
  
      public void testReduceMatMatIntIntInt() {
          Mat src = new Mat(2, 2, CvType.CV_32F) {
              {
                  put(0, 0, 1, 0);
                  put(1, 0, 2, 3);
              }
          };
  
          Core.reduce(src, dst, 1, Core.REDUCE_SUM, CvType.CV_64F);
  
          Mat out = new Mat(2, 1, CvType.CV_64F) {
              {
                  put(0, 0, 1, 5);
              }
          };
          assertMatEqual(out, dst, EPS);
      }
  
      public void testRepeat() {
          Mat src = new Mat(1, 2, CvType.CV_32F, new Scalar(0));
  
          Core.repeat(src, matSize, matSize / 2, dst);
  
          assertMatEqual(gray0_32f, dst, EPS);
      }
  
      public void testScaleAdd() {
          Core.scaleAdd(gray3, 2.0, gray3, dst);
  
          assertMatEqual(gray9, dst);
      }
  
      public void testSetIdentityMat() {
          Core.setIdentity(gray0_32f);
  
          assertMatEqual(grayE_32f, gray0_32f, EPS);
      }
  
      public void testSetIdentityMatScalar() {
          Mat m = gray0_32f;
  
          Core.setIdentity(m, new Scalar(5));
  
          truth = new Mat(m.size(), m.type(), new Scalar(0));
          truth.diag().setTo(new Scalar(5));
          assertMatEqual(truth, m, EPS);
      }
  
      public void testSolveCubic() {
          Mat coeffs = new Mat(1, 4, CvType.CV_32F) {
              {
                  put(0, 0, 1, 6, 11, 6);
              }
          };
  
          assertEquals(3, Core.solveCubic(coeffs, dst));
  
          Mat roots = new Mat(3, 1, CvType.CV_32F) {
              {
                  put(0, 0, -3, -1, -2);
              }
          };
          assertMatEqual(roots, dst, EPS);
      }
  
      public void testSolveMatMatMat() {
          Mat a = new Mat(3, 3, CvType.CV_32F) {
              {
                  put(0, 0, 1, 1, 1);
                  put(1, 0, 1, -2, 2);
                  put(2, 0, 1, 2, 1);
              }
          };
          Mat b = new Mat(3, 1, CvType.CV_32F) {
              {
                  put(0, 0, 0, 4, 2);
              }
          };
  
          assertTrue(Core.solve(a, b, dst));
  
          Mat res = new Mat(3, 1, CvType.CV_32F) {
              {
                  put(0, 0, -12, 2, 10);
              }
          };
          assertMatEqual(res, dst, EPS);
      }
  
      public void testSolveMatMatMatInt() {
          Mat a = new Mat(3, 3, CvType.CV_32F) {
              {
                  put(0, 0, 1, 1, 1);
                  put(1, 0, 1, -2, 2);
                  put(2, 0, 1, 2, 1);
              }
          };
          Mat b = new Mat(3, 1, CvType.CV_32F) {
              {
                  put(0, 0, 0, 4, 2);
              }
          };
  
          assertTrue(Core.solve(a, b, dst, Core.DECOMP_QR | Core.DECOMP_NORMAL));
  
          Mat res = new Mat(3, 1, CvType.CV_32F) {
              {
                  put(0, 0, -12, 2, 10);
              }
          };
          assertMatEqual(res, dst, EPS);
      }
  
      public void testSolvePolyMatMat() {
          Mat coeffs = new Mat(4, 1, CvType.CV_32F) {
              {
                  put(0, 0, -6, 11, -6, 1);
              }
          };
          Mat roots = new Mat();
  
          assertGE(1e-6, Math.abs(Core.solvePoly(coeffs, roots)));
  
          truth = new Mat(3, 1, CvType.CV_32FC2) {
              {
                  put(0, 0, 1, 0, 2, 0, 3, 0);
              }
          };
          assertMatEqual(truth, roots, EPS);
      }
  
      public void testSolvePolyMatMatInt() {
          Mat coeffs = new Mat(4, 1, CvType.CV_32F) {
              {
                  put(0, 0, -6, 11, -6, 1);
              }
          };
          Mat roots = new Mat();
  
          assertEquals(10.198039027185569, Core.solvePoly(coeffs, roots, 1));
  
          truth = new Mat(3, 1, CvType.CV_32FC2) {
              {
                  put(0, 0, 1, 0, -1, 2, -2, 12);
              }
          };
          assertMatEqual(truth, roots, EPS);
      }
  
      public void testSort() {
          Mat submat = gray0.submat(0, gray0.rows() / 2, 0, gray0.cols() / 2);
          submat.setTo(new Scalar(1.0));
  
          Core.sort(gray0, dst, Core.SORT_EVERY_ROW);
  
          submat = dst.submat(0, dst.rows() / 2, dst.cols() / 2, dst.cols());
          assertTrue(submat.total() == Core.countNonZero(submat));
  
          Core.sort(gray0, dst, Core.SORT_EVERY_COLUMN);
  
          submat = dst.submat(dst.rows() / 2, dst.rows(), 0, dst.cols() / 2);
  
          assertTrue(submat.total() == Core.countNonZero(submat));
      }
  
      public void testSortIdx() {
          Mat a = Mat.eye(3, 3, CvType.CV_8UC1);
          Mat b = new Mat();
  
          Core.sortIdx(a, b, Core.SORT_EVERY_ROW | Core.SORT_ASCENDING);
  
          truth = new Mat(3, 3, CvType.CV_32SC1) {
              {
                  put(0, 0, 1, 2, 0);
                  put(1, 0, 0, 2, 1);
                  put(2, 0, 0, 1, 2);
              }
          };
          assertMatEqual(truth, b);
      }
  
      public void testSplit() {
          Mat m = getMat(CvType.CV_8UC3, 1, 2, 3);
          ArrayList<Mat> cois = new ArrayList<Mat>();
  
          Core.split(m, cois);
  
          assertMatEqual(gray1, cois.get(0));
          assertMatEqual(gray2, cois.get(1));
          assertMatEqual(gray3, cois.get(2));
      }
  
      public void testSqrt() {
          Core.sqrt(gray9_32f, dst);
  
          assertMatEqual(gray3_32f, dst, EPS);
  
          Mat rgba144 = new Mat(matSize, matSize, CvType.CV_32FC4, Scalar.all(144));
          Mat rgba12 = new Mat(matSize, matSize, CvType.CV_32FC4, Scalar.all(12));
  
          Core.sqrt(rgba144, dst);
  
          assertMatEqual(rgba12, dst, EPS);
      }
  
      public void testSubtractMatMatMat() {
          Core.subtract(gray128, gray1, dst);
  
          assertMatEqual(gray127, dst);
      }
  
      public void testSubtractMatMatMatMat() {
          Mat mask = makeMask(gray1.clone());
          dst = gray128.clone();
  
          Core.subtract(gray128, gray1, dst, mask);
  
          assertMatEqual(makeMask(gray127, 128), dst);
      }
  
      public void testSubtractMatMatMatMatInt() {
          Core.subtract(gray3, gray2, dst, gray1, CvType.CV_32F);
  
          assertMatEqual(gray1_32f, dst, EPS);
      }
  
      public void testSumElems() {
          Mat src = new Mat(4, 4, CvType.CV_8U, new Scalar(10));
  
          Scalar res1 = Core.sumElems(src);
  
          assertScalarEqual(new Scalar(160), res1, EPS);
      }
  
      public void testSVBackSubst() {
          Mat w = new Mat(2, 2, CvType.CV_32FC1, new Scalar(2));
          Mat u = new Mat(2, 2, CvType.CV_32FC1, new Scalar(4));
          Mat vt = new Mat(2, 2, CvType.CV_32FC1, new Scalar(2));
          Mat rhs = new Mat(2, 2, CvType.CV_32FC1, new Scalar(1));
  
          Core.SVBackSubst(w, u, vt, rhs, dst);
  
          Mat truth = new Mat(2, 2, CvType.CV_32FC1, new Scalar(16));
          assertMatEqual(truth, dst, EPS);
      }
  
      public void testSVDecompMatMatMatMat() {
          Mat src = new Mat(1, 4, CvType.CV_32FC1) {
              {
                  put(0, 0, 1, 4, 8, 6);
              }
          };
          Mat w = new Mat();
          Mat u = new Mat();
          Mat vt = new Mat();
  
          Core.SVDecomp(src, w, u, vt);
  
          Mat truthW = new Mat(1, 1, CvType.CV_32FC1, new Scalar(10.816654));
          Mat truthU = new Mat(1, 1, CvType.CV_32FC1, new Scalar(1));
          Mat truthVT = new Mat(1, 4, CvType.CV_32FC1) {
              {
                  put(0, 0, 0.09245003, 0.36980012, 0.73960024, 0.5547002);
              }
          };
          assertMatEqual(truthW, w, EPS);
          assertMatEqual(truthU, u, EPS);
          assertMatEqual(truthVT, vt, EPS);
      }
  
      public void testSVDecompMatMatMatMatInt() {
          Mat src = new Mat(1, 4, CvType.CV_32FC1) {
              {
                  put(0, 0, 1, 4, 8, 6);
              }
          };
          Mat w = new Mat();
          Mat u = new Mat();
          Mat vt = new Mat();
  
          Core.SVDecomp(src, w, u, vt, Core.SVD_NO_UV);
  
          Mat truthW = new Mat(1, 1, CvType.CV_32FC1, new Scalar(10.816654));
          assertMatEqual(truthW, w, EPS);
          assertTrue(u.empty());
          assertTrue(vt.empty());
      }
  
      public void testTrace() {
          Scalar s = Core.trace(gray1);
  
          assertEquals(new Scalar(matSize), s);
      }
  
      public void testTransform() {
          Mat src = new Mat(2, 2, CvType.CV_32F, new Scalar(55));
          Mat m = Mat.eye(2, 2, CvType.CV_32FC1);
  
          Core.transform(src, dst, m);
  
          truth = new Mat(2, 2, CvType.CV_32FC2, new Scalar(55, 1));
          assertMatEqual(truth, dst, EPS);
      }
  
      public void testTranspose() {
          gray0.submat(0, gray0.rows() / 2, 0, gray0.cols()).setTo(new Scalar(1));
          Mat destination = getMat(CvType.CV_8U, 0);
  
          Core.transpose(gray0, destination);
  
          Mat subdst = destination.submat(0, destination.rows(), 0, destination.cols() / 2);
          assertTrue(subdst.total() == Core.countNonZero(subdst));
      }
  
      public void testVconcat() {
          List<Mat> mats = Arrays.asList(Mat.eye(3, 3, CvType.CV_8U), Mat.zeros(2, 3, CvType.CV_8U));
  
          Core.vconcat(mats, dst);
  
          assertMatEqual(Mat.eye(5, 3, CvType.CV_8U), dst);
  
      }
  
      public void testCopyMakeBorderMatMatIntIntIntIntInt() {
          Mat src = new Mat(2, 2, CvType.CV_32F, new Scalar(1));
          int border = 2;
  
          Core.copyMakeBorder(src, dst, border, border, border, border, Core.BORDER_REPLICATE);
  
          truth = new Mat(6, 6, CvType.CV_32F, new Scalar(1));
          assertMatEqual(truth, dst, EPS);
      }
  
      public void testCopyMakeBorderMatMatIntIntIntIntIntScalar() {
          Mat src = new Mat(2, 2, CvType.CV_32F, new Scalar(1));
  
          Scalar value = new Scalar(0);
          int border = 2;
  
          Core.copyMakeBorder(src, dst, border, border, border, border, Core.BORDER_REPLICATE, value);
          // TODO_: write better test (use Core.BORDER_CONSTANT)
  
          truth = new Mat(6, 6, CvType.CV_32F, new Scalar(1));
          assertMatEqual(truth, dst, EPS);
      }
  
      public void testBorderInterpolate() {
          float val1 = Core.borderInterpolate(100, 150, Core.BORDER_REFLECT_101);
          assertEquals(100f, val1);
  
          float val2 = Core.borderInterpolate(-5, 10, Core.BORDER_WRAP);
          assertEquals(5f, val2);
      }
  
      public void testVersion() {
          assertEquals(Core.VERSION_MAJOR, Core.getVersionMajor());
          assertEquals(Core.VERSION_MINOR, Core.getVersionMinor());
          assertEquals(Core.VERSION_REVISION, Core.getVersionRevision());
          assertEquals(Core.VERSION, Core.getVersionString());
      }
  
  }
  