1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4 
5 #include "test_precomp.hpp"
6 
7 namespace opencv_test { namespace {
8 
9 
TEST(ximgproc_fourierdescriptors,test_FD_AND_FIT)10 TEST(ximgproc_fourierdescriptors,test_FD_AND_FIT)
11 {
12     Mat fd;
13     vector<Point2f> ctr(16);
14     float Rx = 100, Ry = 100;
15     Point2f g(0, 0);
16     float angleOri = 0;
17     for (int i = 0; i < static_cast<int>(ctr.size()); i++)
18     {
19         float theta = static_cast<float>(2 * CV_PI / static_cast<int>(ctr.size()) * i + angleOri);
20         ctr[i] = Point2f(Rx * cos(theta) + g.x, Ry * sin(theta) + g.y);
21 
22     }
23     ximgproc::fourierDescriptor(ctr, fd);
24     CV_Assert(cv::norm(fd.at<Vec2f>(0, 0)) < ctr.size() * FLT_EPSILON && cv::norm(fd.at<Vec2f>(0, 1) - Vec2f(Rx, 0)) < ctr.size() * FLT_EPSILON);
25     Rx = 100, Ry = 50;
26     g = Point2f(50, 20);
27     for (int i = 0; i < static_cast<int>(ctr.size()); i++)
28     {
29         float theta = static_cast<float>(2 * CV_PI / static_cast<int>(ctr.size()) * i + angleOri);
30         ctr[i] = Point2f(Rx * cos(theta) + g.x, Ry * sin(theta) + g.y);
31     }
32     ximgproc::fourierDescriptor(ctr, fd);
33     CV_Assert(cv::norm(fd.at<Vec2f>(0, 0) - Vec2f(g)) < 1 &&
34         fabs(fd.at<Vec2f>(0, 1)[0] + fd.at<Vec2f>(0, static_cast<int>(ctr.size()) - 1)[0] - Rx) < 1 &&
35         fabs(fd.at<Vec2f>(0, 1)[0] - fd.at<Vec2f>(0, static_cast<int>(ctr.size()) - 1)[0] - Ry) < 1);
36     Rx = 70, Ry = 100;
37     g = Point2f(30, 100);
38     angleOri = static_cast<float>(CV_PI / 4);
39     for (int i = 0; i < static_cast<int>(ctr.size()); i++)
40     {
41         float theta = static_cast<float>(2 * CV_PI / static_cast<int>(ctr.size()) * i + CV_PI / 4);
42         ctr[i] = Point2f(Rx * cos(theta) + g.x, Ry * sin(theta) + g.y);
43     }
44     ximgproc::fourierDescriptor(ctr, fd);
45     CV_Assert(cv::norm(fd.at<Vec2f>(0, 0) - Vec2f(g)) < 1);
46     CV_Assert(cv::norm(Vec2f((Rx + Ry)*cos(angleOri) / 2, (Rx + Ry)*sin(angleOri) / 2) - fd.at<Vec2f>(0, 1)) < 1);
47     CV_Assert(cv::norm(Vec2f((Rx - Ry)*cos(angleOri) / 2, -(Rx - Ry)*sin(angleOri) / 2) - fd.at<Vec2f>(0, static_cast<int>(ctr.size()) - 1)) < 1);
48 
49     RNG rAlea;
50     g.x = 0; g.y = 0;
51     ctr.resize(256);
52     for (int i = 0; i < static_cast<int>(ctr.size()); i++)
53     {
54         ctr[i] = Point2f(rAlea.uniform(0.0F, 1.0F), rAlea.uniform(0.0F, 1.0F));
55         g += ctr[i];
56     }
57     g.x = g.x / ctr.size();
58     g.y = g.y / ctr.size();
59     double rotAngle = 35;
60     double s = 0.1515;
61     Mat r = getRotationMatrix2D(g, rotAngle, 0.1515);
62     vector<Point2f> unknownCtr;
63     vector<Point2f> ctrShift;
64     int valShift = 170;
65     for (int i = 0; i < static_cast<int>(ctr.size()); i++)
66         ctrShift.push_back(ctr[(i + valShift) % ctr.size()]);
67     cv::transform(ctrShift, unknownCtr, r);
68     ximgproc::ContourFitting fit;
69     fit.setFDSize(16);
70     Mat t;
71     double dist;
72     fit.estimateTransformation(unknownCtr, ctr, t, &dist, false);
73     CV_Assert(fabs(t.at<double>(0, 0)*ctr.size() + valShift) < 10 || fabs((1 - t.at<double>(0, 0))*ctr.size() - valShift) < 10);
74     CV_Assert(fabs(t.at<double>(0, 1) - rotAngle / 180.*CV_PI) < 0.1);
75     CV_Assert(fabs(t.at<double>(0, 2) - 1 / s) < 0.1);
76     ctr.resize(4);
77     ctr[0] = Point2f(0, 0);
78     ctr[1] = Point2f(16, 0);
79     ctr[2] = Point2f(16, 16);
80     ctr[3] = Point2f(0, 16);
81     double squareArea = contourArea(ctr), lengthSquare = arcLength(ctr, true);
82     Mat ctrs;
83     ximgproc::contourSampling(ctr, ctrs, 64);
84     CV_Assert(fabs(squareArea - contourArea(ctrs)) < FLT_EPSILON);
85     CV_Assert(fabs(lengthSquare - arcLength(ctrs, true)) < FLT_EPSILON);
86 }
87 
88 
89 
90 }} // namespace
91