test_boundingrect.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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 "opencv2/core/types.hpp"
  5. #include "test_precomp.hpp"
  6. using namespace cv;
  7. using namespace std;
  8. namespace opencv_test { namespace {
  9. template <typename T>
  10. cv::Rect calcBoundingRect(Mat pts)
  11. {
  12. CV_Assert(pts.type() == CV_32FC2 || pts.type() == CV_32SC2);
  13. CV_Assert(pts.size().width == 1 && pts.size().height > 0);
  14. const int N = pts.size().height;
  15. // NOTE: using ::lowest(), not ::min()
  16. T min_w = std::numeric_limits<T>::max(), max_w = std::numeric_limits<T>::lowest();
  17. T min_h = min_w, max_h = max_w;
  18. for (int i = 0; i < N; ++i)
  19. {
  20. const Point_<T> & pt = pts.at<Point_<T>>(i, 0);
  21. min_w = std::min<T>(pt.x, min_w);
  22. max_w = std::max<T>(pt.x, max_w);
  23. min_h = std::min<T>(pt.y, min_h);
  24. max_h = std::max<T>(pt.y, max_h);
  25. }
  26. return Rect(cvFloor(min_w), cvFloor(min_h), cvFloor(max_w) - cvFloor(min_w) + 1, cvFloor(max_h) - cvFloor(min_h) + 1);
  27. }
  28. typedef ::testing::TestWithParam<int> Imgproc_BoundingRect_Types;
  29. TEST_P(Imgproc_BoundingRect_Types, accuracy)
  30. {
  31. const int depth = GetParam();
  32. RNG& rng = ::cvtest::TS::ptr()->get_rng();
  33. for (int k = 0; k < 1000; ++k)
  34. {
  35. SCOPED_TRACE(cv::format("k=%d", k));
  36. const int sz = rng.uniform(1, 10000);
  37. Mat src(sz, 1, CV_MAKETYPE(depth, 2));
  38. rng.fill(src, RNG::UNIFORM, Scalar(-100000, -100000), Scalar(100000, 100000));
  39. Rect reference;
  40. if (depth == CV_32F)
  41. reference = calcBoundingRect<float>(src);
  42. else if (depth == CV_32S)
  43. reference = calcBoundingRect<int>(src);
  44. else
  45. CV_Error(Error::StsError, "Test error");
  46. Rect result = cv::boundingRect(src);
  47. EXPECT_EQ(reference, result);
  48. }
  49. }
  50. TEST_P(Imgproc_BoundingRect_Types, alignment)
  51. {
  52. const int depth = GetParam();
  53. const int SZ = 100;
  54. int idata[SZ];
  55. float fdata[SZ];
  56. for (int i = 0; i < SZ; ++i)
  57. {
  58. idata[i] = i;
  59. fdata[i] = (float)i;
  60. }
  61. for (int i = 0; i < 10; ++i)
  62. {
  63. for (int len = 1; len < 40; ++len)
  64. {
  65. SCOPED_TRACE(cv::format("i=%d, len=%d", i, len));
  66. Mat sub(len, 1, CV_MAKETYPE(depth, 2), (depth == CV_32S) ? (void*)(idata + i) : (void*)(fdata + i));
  67. EXPECT_NO_THROW(boundingRect(sub));
  68. }
  69. }
  70. }
  71. INSTANTIATE_TEST_CASE_P(, Imgproc_BoundingRect_Types, ::testing::Values(CV_32S, CV_32F));
  72. TEST(Imgproc_BoundingRect, bug_24217)
  73. {
  74. for (int image_width = 3; image_width < 20; image_width++)
  75. {
  76. for (int image_height = 1; image_height < 15; image_height++)
  77. {
  78. cv::Rect rect(0, image_height - 1, 3, 1);
  79. cv::Mat image(cv::Size(image_width, image_height), CV_8UC1, cv::Scalar(0));
  80. image(rect) = 255;
  81. ASSERT_EQ(boundingRect(image), rect);
  82. }
  83. }
  84. }
  85. }} // namespace