Home | History | Annotate | Download | only in test
      1 package org.opencv.test;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.File;
      5 import java.io.FileOutputStream;
      6 import java.io.FileReader;
      7 import java.io.IOException;
      8 import java.nio.channels.FileChannel;
      9 import java.nio.charset.Charset;
     10 import java.util.List;
     11 
     12 import junit.framework.TestCase;
     13 
     14 import org.opencv.core.Core;
     15 import org.opencv.core.CvType;
     16 import org.opencv.core.Mat;
     17 import org.opencv.core.Point;
     18 import org.opencv.core.Point3;
     19 import org.opencv.core.Rect;
     20 import org.opencv.core.Scalar;
     21 import org.opencv.core.Size;
     22 import org.opencv.core.DMatch;
     23 import org.opencv.core.KeyPoint;
     24 import org.opencv.imgcodecs.Imgcodecs;
     25 
     26 import android.util.Log;
     27 
     28 public class OpenCVTestCase extends TestCase {
     29     //change to 'true' to unblock fail on fail("Not yet implemented")
     30     public static final boolean passNYI = true;
     31 
     32     protected static boolean isTestCaseEnabled = true;
     33 
     34     protected static final int matSize = 10;
     35     protected static final double EPS = 0.001;
     36     protected static final double weakEPS = 0.5;
     37 
     38     private static final String TAG = "OpenCVTestCase";
     39 
     40     protected Mat dst;
     41     protected Mat truth;
     42 
     43     protected Scalar colorBlack;
     44     protected Scalar colorWhite;
     45 
     46     // Naming notation: <channels info>_[depth]_[dimensions]_value
     47     // examples: gray0 - single channel 8U 2d Mat filled with 0
     48     // grayRnd - single channel 8U 2d Mat filled with random numbers
     49     // gray0_32f_1d
     50 
     51     // TODO: OpenCVTestCase refactorings
     52     // - rename matrices
     53     // - create methods gray0() and create src1 explicitly
     54     // - create some masks
     55     // - use truth member everywhere - remove truth from base class - each test
     56     // fixture should use own truth filed
     57 
     58     protected Mat gray0;
     59     protected Mat gray1;
     60     protected Mat gray2;
     61     protected Mat gray3;
     62     protected Mat gray9;
     63     protected Mat gray127;
     64     protected Mat gray128;
     65     protected Mat gray255;
     66     protected Mat grayRnd;
     67 
     68     protected Mat gray_16u_256;
     69     protected Mat gray_16s_1024;
     70 
     71     protected Mat gray0_32f;
     72     protected Mat gray1_32f;
     73     protected Mat gray3_32f;
     74     protected Mat gray9_32f;
     75     protected Mat gray255_32f;
     76     protected Mat grayE_32f;
     77     protected Mat grayRnd_32f;
     78 
     79     protected Mat gray0_32f_1d;
     80 
     81     protected Mat gray0_64f;
     82     protected Mat gray0_64f_1d;
     83 
     84     protected Mat rgba0;
     85     protected Mat rgba128;
     86 
     87     protected Mat rgbLena;
     88     protected Mat grayChess;
     89 
     90     protected Mat v1;
     91     protected Mat v2;
     92 
     93     @Override
     94     protected void setUp() throws Exception {
     95         super.setUp();
     96 
     97         dst = new Mat();
     98         assertTrue(dst.empty());
     99         truth = null;
    100 
    101         colorBlack = new Scalar(0);
    102         colorWhite = new Scalar(255, 255, 255);
    103 
    104         gray0 = new Mat(matSize, matSize, CvType.CV_8U, new Scalar(0));
    105         gray1 = new Mat(matSize, matSize, CvType.CV_8U, new Scalar(1));
    106         gray2 = new Mat(matSize, matSize, CvType.CV_8U, new Scalar(2));
    107         gray3 = new Mat(matSize, matSize, CvType.CV_8U, new Scalar(3));
    108         gray9 = new Mat(matSize, matSize, CvType.CV_8U, new Scalar(9));
    109         gray127 = new Mat(matSize, matSize, CvType.CV_8U, new Scalar(127));
    110         gray128 = new Mat(matSize, matSize, CvType.CV_8U, new Scalar(128));
    111         gray255 = new Mat(matSize, matSize, CvType.CV_8U, new Scalar(255));
    112 
    113         grayRnd = new Mat(matSize, matSize, CvType.CV_8U);
    114         Core.randu(grayRnd, 0, 256);
    115 
    116         gray_16u_256 = new Mat(matSize, matSize, CvType.CV_16U, new Scalar(256));
    117         gray_16s_1024 = new Mat(matSize, matSize, CvType.CV_16S, new Scalar(1024));
    118 
    119         gray0_32f = new Mat(matSize, matSize, CvType.CV_32F, new Scalar(0.0));
    120         gray1_32f = new Mat(matSize, matSize, CvType.CV_32F, new Scalar(1.0));
    121         gray3_32f = new Mat(matSize, matSize, CvType.CV_32F, new Scalar(3.0));
    122         gray9_32f = new Mat(matSize, matSize, CvType.CV_32F, new Scalar(9.0));
    123         gray255_32f = new Mat(matSize, matSize, CvType.CV_32F, new Scalar(255.0));
    124         grayE_32f = new Mat(matSize, matSize, CvType.CV_32F);
    125         grayE_32f = Mat.eye(matSize, matSize, CvType.CV_32FC1);
    126         grayRnd_32f = new Mat(matSize, matSize, CvType.CV_32F);
    127         Core.randu(grayRnd_32f, 0, 256);
    128 
    129         gray0_64f = new Mat(matSize, matSize, CvType.CV_64F, new Scalar(0.0));
    130 
    131         gray0_32f_1d = new Mat(1, matSize, CvType.CV_32F, new Scalar(0.0));
    132         gray0_64f_1d = new Mat(1, matSize, CvType.CV_64F, new Scalar(0.0));
    133 
    134         rgba0 = new Mat(matSize, matSize, CvType.CV_8UC4, Scalar.all(0));
    135         rgba128 = new Mat(matSize, matSize, CvType.CV_8UC4, Scalar.all(128));
    136 
    137         rgbLena = Imgcodecs.imread(OpenCVTestRunner.LENA_PATH);
    138         grayChess = Imgcodecs.imread(OpenCVTestRunner.CHESS_PATH, 0);
    139 
    140         v1 = new Mat(1, 3, CvType.CV_32F);
    141         v1.put(0, 0, 1.0, 3.0, 2.0);
    142         v2 = new Mat(1, 3, CvType.CV_32F);
    143         v2.put(0, 0, 2.0, 1.0, 3.0);
    144     }
    145 
    146     @Override
    147     protected void tearDown() throws Exception {
    148 
    149         gray0.release();
    150         gray1.release();
    151         gray2.release();
    152         gray3.release();
    153         gray9.release();
    154         gray127.release();
    155         gray128.release();
    156         gray255.release();
    157         gray_16u_256.release();
    158         gray_16s_1024.release();
    159         grayRnd.release();
    160         gray0_32f.release();
    161         gray1_32f.release();
    162         gray3_32f.release();
    163         gray9_32f.release();
    164         gray255_32f.release();
    165         grayE_32f.release();
    166         grayE_32f.release();
    167         grayRnd_32f.release();
    168         gray0_32f_1d.release();
    169         gray0_64f.release();
    170         gray0_64f_1d.release();
    171         rgba0.release();
    172         rgba128.release();
    173         rgbLena.release();
    174         grayChess.release();
    175         v1.release();
    176         v2.release();
    177 
    178         super.tearDown();
    179     }
    180 
    181     @Override
    182     protected void runTest() throws Throwable {
    183         // Do nothing if the precondition does not hold.
    184         if (isTestCaseEnabled) {
    185             super.runTest();
    186         } else {
    187             Log.e(TAG, "Test case \"" + this.getClass().getName() + "\" disabled!");
    188         }
    189     }
    190 
    191     protected Mat getMat(int type, double... vals)
    192     {
    193         return new Mat(matSize, matSize, type, new Scalar(vals));
    194     }
    195 
    196     protected Mat makeMask(Mat m, double... vals)
    197     {
    198         m.submat(0, m.rows(), 0, m.cols() / 2).setTo(new Scalar(vals));
    199         return m;
    200     }
    201 
    202     public static void fail(String msg) {
    203         if(msg == "Not yet implemented" && passNYI)
    204             return;
    205         TestCase.fail(msg);
    206     }
    207 
    208     public static <E extends Number> void assertListEquals(List<E> list1, List<E> list2) {
    209         if (list1.size() != list2.size()) {
    210             throw new UnsupportedOperationException();
    211         }
    212 
    213         if (!list1.isEmpty())
    214         {
    215             if (list1.get(0) instanceof Float || list1.get(0) instanceof Double)
    216                 throw new UnsupportedOperationException();
    217         }
    218 
    219         for (int i = 0; i < list1.size(); i++)
    220             assertEquals(list1.get(i), list2.get(i));
    221     }
    222 
    223     public static <E extends Number> void assertListEquals(List<E> list1, List<E> list2, double epsilon) {
    224         if (list1.size() != list2.size()) {
    225             throw new UnsupportedOperationException();
    226         }
    227 
    228         for (int i = 0; i < list1.size(); i++)
    229             assertTrue(Math.abs(list1.get(i).doubleValue() - list2.get(i).doubleValue()) <= epsilon);
    230     }
    231 
    232     public static <E extends Number> void assertArrayEquals(E[] ar1, E[] ar2, double epsilon) {
    233         if (ar1.length != ar2.length) {
    234             fail("Arrays have different sizes.");
    235         }
    236 
    237         for (int i = 0; i < ar1.length; i++)
    238             assertEquals(ar1[i].doubleValue(), ar2[i].doubleValue(), epsilon);
    239             //assertTrue(Math.abs(ar1[i].doubleValue() - ar2[i].doubleValue()) <= epsilon);
    240     }
    241 
    242     public static void assertArrayEquals(double[] ar1, double[] ar2, double epsilon) {
    243         if (ar1.length != ar2.length) {
    244             fail("Arrays have different sizes.");
    245         }
    246 
    247         for (int i = 0; i < ar1.length; i++)
    248             assertEquals(ar1[i], ar2[i], epsilon);
    249             //assertTrue(Math.abs(ar1[i].doubleValue() - ar2[i].doubleValue()) <= epsilon);
    250     }
    251 
    252     public static void assertListMatEquals(List<Mat> list1, List<Mat> list2, double epsilon) {
    253         if (list1.size() != list2.size()) {
    254             throw new UnsupportedOperationException();
    255         }
    256 
    257         for (int i = 0; i < list1.size(); i++)
    258             assertMatEqual(list1.get(i), list2.get(i), epsilon);
    259     }
    260 
    261     public static void assertListPointEquals(List<Point> list1, List<Point> list2, double epsilon) {
    262         if (list1.size() != list2.size()) {
    263             throw new UnsupportedOperationException();
    264         }
    265 
    266         for (int i = 0; i < list1.size(); i++)
    267             assertPointEquals(list1.get(i), list2.get(i), epsilon);
    268     }
    269 
    270     public static void assertArrayPointsEquals(Point[] vp1, Point[] vp2, double epsilon) {
    271         if (vp1.length != vp2.length) {
    272             fail("Arrays have different sizes.");
    273         }
    274 
    275         for (int i = 0; i < vp1.length; i++)
    276             assertPointEquals(vp1[i], vp2[i], epsilon);
    277     }
    278     public static void assertListPoint3Equals(List<Point3> list1, List<Point3> list2, double epsilon) {
    279         if (list1.size() != list2.size()) {
    280             throw new UnsupportedOperationException();
    281         }
    282 
    283         for (int i = 0; i < list1.size(); i++)
    284             assertPoint3Equals(list1.get(i), list2.get(i), epsilon);
    285     }
    286 
    287     public static void assertListRectEquals(List<Rect> list1, List<Rect> list2) {
    288         if (list1.size() != list2.size()) {
    289             throw new UnsupportedOperationException();
    290         }
    291 
    292         for (int i = 0; i < list1.size(); i++)
    293             assertRectEquals(list1.get(i), list2.get(i));
    294     }
    295 
    296     public static void assertRectEquals(Rect expected, Rect actual) {
    297         String msg = "expected:<" + expected + "> but was:<" + actual + ">";
    298         assertEquals(msg, expected.x, actual.x);
    299         assertEquals(msg, expected.y, actual.y);
    300         assertEquals(msg, expected.width, actual.width);
    301         assertEquals(msg, expected.height, actual.height);
    302     }
    303 
    304     public static void assertMatEqual(Mat m1, Mat m2) {
    305         compareMats(m1, m2, true);
    306     }
    307 
    308     public static void assertMatNotEqual(Mat m1, Mat m2) {
    309         compareMats(m1, m2, false);
    310     }
    311 
    312     public static void assertMatEqual(Mat expected, Mat actual, double eps) {
    313         compareMats(expected, actual, eps, true);
    314     }
    315 
    316     public static void assertMatNotEqual(Mat expected, Mat actual, double eps) {
    317         compareMats(expected, actual, eps, false);
    318     }
    319 
    320     public static void assertKeyPointEqual(KeyPoint expected, KeyPoint actual, double eps) {
    321         String msg = "expected:<" + expected + "> but was:<" + actual + ">";
    322         assertTrue(msg, Math.hypot(expected.pt.x - actual.pt.x, expected.pt.y - actual.pt.y) < eps);
    323         assertTrue(msg, Math.abs(expected.size - actual.size) < eps);
    324         assertTrue(msg, Math.abs(expected.angle - actual.angle) < eps);
    325         assertTrue(msg, Math.abs(expected.response - actual.response) < eps);
    326         assertEquals(msg, expected.octave, actual.octave);
    327         assertEquals(msg, expected.class_id, actual.class_id);
    328     }
    329 
    330     public static void assertListKeyPointEquals(List<KeyPoint> expected, List<KeyPoint> actual, double epsilon) {
    331         assertEquals(expected.size(), actual.size());
    332         for (int i = 0; i < expected.size(); i++)
    333             assertKeyPointEqual(expected.get(i), actual.get(i), epsilon);
    334     }
    335 
    336     public static void assertDMatchEqual(DMatch expected, DMatch actual, double eps) {
    337         String msg = "expected:<" + expected + "> but was:<" + actual + ">";
    338         assertEquals(msg, expected.queryIdx, actual.queryIdx);
    339         assertEquals(msg, expected.trainIdx, actual.trainIdx);
    340         assertEquals(msg, expected.imgIdx, actual.imgIdx);
    341         assertTrue(msg, Math.abs(expected.distance - actual.distance) < eps);
    342     }
    343 
    344     public static void assertScalarEqual(Scalar expected, Scalar actual, double eps) {
    345         String msg = "expected:<" + expected + "> but was:<" + actual + ">";
    346         assertTrue(msg, Math.abs(expected.val[0] - actual.val[0]) < eps);
    347         assertTrue(msg, Math.abs(expected.val[1] - actual.val[1]) < eps);
    348         assertTrue(msg, Math.abs(expected.val[2] - actual.val[2]) < eps);
    349         assertTrue(msg, Math.abs(expected.val[3] - actual.val[3]) < eps);
    350     }
    351 
    352     public static void assertArrayDMatchEquals(DMatch[] expected, DMatch[] actual, double epsilon) {
    353         assertEquals(expected.length, actual.length);
    354         for (int i = 0; i < expected.length; i++)
    355             assertDMatchEqual(expected[i], actual[i], epsilon);
    356     }
    357 
    358     public static void assertListDMatchEquals(List<DMatch> expected, List<DMatch> actual, double epsilon) {
    359         DMatch expectedArray[] = expected.toArray(new DMatch[0]);
    360         DMatch actualArray[]   = actual.toArray(new DMatch[0]);
    361         assertArrayDMatchEquals(expectedArray, actualArray, epsilon);
    362     }
    363 
    364     public static void assertPointEquals(Point expected, Point actual, double eps) {
    365         String msg = "expected:<" + expected + "> but was:<" + actual + ">";
    366         assertEquals(msg, expected.x, actual.x, eps);
    367         assertEquals(msg, expected.y, actual.y, eps);
    368     }
    369 
    370     public static void assertSizeEquals(Size expected, Size actual, double eps) {
    371         String msg = "expected:<" + expected + "> but was:<" + actual + ">";
    372         assertEquals(msg, expected.width, actual.width, eps);
    373         assertEquals(msg, expected.height, actual.height, eps);
    374     }
    375 
    376     public static void assertPoint3Equals(Point3 expected, Point3 actual, double eps) {
    377         String msg = "expected:<" + expected + "> but was:<" + actual + ">";
    378         assertEquals(msg, expected.x, actual.x, eps);
    379         assertEquals(msg, expected.y, actual.y, eps);
    380         assertEquals(msg, expected.z, actual.z, eps);
    381     }
    382 
    383     static private void compareMats(Mat expected, Mat actual, boolean isEqualityMeasured) {
    384         if (expected.type() != actual.type() || expected.cols() != actual.cols() || expected.rows() != actual.rows()) {
    385             throw new UnsupportedOperationException("Can not compare " + expected + " and " + actual);
    386         }
    387 
    388         if (expected.depth() == CvType.CV_32F || expected.depth() == CvType.CV_64F) {
    389             if (isEqualityMeasured)
    390                 throw new UnsupportedOperationException(
    391                         "Floating-point Mats must not be checked for exact match. Use assertMatEqual(Mat expected, Mat actual, double eps) instead.");
    392             else
    393                 throw new UnsupportedOperationException(
    394                         "Floating-point Mats must not be checked for exact match. Use assertMatNotEqual(Mat expected, Mat actual, double eps) instead.");
    395         }
    396 
    397         Mat diff = new Mat();
    398         Core.absdiff(expected, actual, diff);
    399         Mat reshaped = diff.reshape(1);
    400         int mistakes = Core.countNonZero(reshaped);
    401 
    402         reshaped.release();
    403         diff.release();
    404 
    405         if (isEqualityMeasured)
    406             assertTrue("Mats are different in " + mistakes + " points", 0 == mistakes);
    407         else
    408             assertFalse("Mats are equal", 0 == mistakes);
    409     }
    410 
    411     static private void compareMats(Mat expected, Mat actual, double eps, boolean isEqualityMeasured) {
    412         if (expected.type() != actual.type() || expected.cols() != actual.cols() || expected.rows() != actual.rows()) {
    413             throw new UnsupportedOperationException("Can not compare " + expected + " and " + actual);
    414         }
    415 
    416         Mat diff = new Mat();
    417         Core.absdiff(expected, actual, diff);
    418         double maxDiff = Core.norm(diff, Core.NORM_INF);
    419 
    420         if (isEqualityMeasured)
    421             assertTrue("Max difference between expected and actiual Mats is "+ maxDiff + ", that bigger than " + eps,
    422                     Core.checkRange(diff, true, 0.0, eps));
    423         else
    424             assertFalse("Max difference between expected and actiual Mats is "+ maxDiff + ", that less than " + eps,
    425                     Core.checkRange(diff, true, 0.0, eps));
    426     }
    427 
    428     protected static String readFile(String path) {
    429         try {
    430         BufferedReader br = new BufferedReader(new FileReader(path));
    431         String line;
    432         StringBuffer result = new StringBuffer();
    433         while ((line = br.readLine()) != null) {
    434             result.append(line);
    435             result.append("\n");
    436         }
    437         return result.toString();
    438         } catch (IOException e) {
    439             OpenCVTestRunner.Log("Failed to read file \"" + path
    440                     + "\". Exception is thrown: " + e);
    441             return null;
    442         }
    443     }
    444 
    445     protected static void writeFile(String path, String content) {
    446         FileOutputStream stream = null;
    447         try {
    448             stream = new FileOutputStream(new File(path));
    449             FileChannel fc = stream.getChannel();
    450             fc.write(Charset.defaultCharset().encode(content));
    451         } catch (IOException e) {
    452             OpenCVTestRunner.Log("Failed to write file \"" + path
    453                     + "\". Exception is thrown: " + e);
    454         } finally {
    455             if (stream != null)
    456                 try {
    457                     stream.close();
    458                 } catch (IOException e) {
    459                     OpenCVTestRunner.Log("Exception is thrown: " + e);
    460                 }
    461         }
    462     }
    463 
    464 }
    465