test_fourier_descriptors.cpp 3.6 KB

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