test_lsd.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  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. const Size img_size(640, 480);
  7. const int LSD_TEST_SEED = 0x134679;
  8. const int EPOCHS = 20;
  9. class LSDBase : public testing::Test
  10. {
  11. public:
  12. LSDBase() { }
  13. protected:
  14. Mat test_image;
  15. vector<Vec4f> lines;
  16. RNG rng;
  17. int passedtests;
  18. void GenerateWhiteNoise(Mat& image);
  19. void GenerateConstColor(Mat& image);
  20. void GenerateLines(Mat& image, const unsigned int numLines);
  21. void GenerateRotatedRect(Mat& image);
  22. virtual void SetUp();
  23. };
  24. class Imgproc_LSD_ADV: public LSDBase
  25. {
  26. public:
  27. Imgproc_LSD_ADV() { }
  28. protected:
  29. };
  30. class Imgproc_LSD_STD: public LSDBase
  31. {
  32. public:
  33. Imgproc_LSD_STD() { }
  34. protected:
  35. };
  36. class Imgproc_LSD_NONE: public LSDBase
  37. {
  38. public:
  39. Imgproc_LSD_NONE() { }
  40. protected:
  41. };
  42. class Imgproc_LSD_Common : public LSDBase
  43. {
  44. public:
  45. Imgproc_LSD_Common() { }
  46. protected:
  47. };
  48. void LSDBase::GenerateWhiteNoise(Mat& image)
  49. {
  50. image = Mat(img_size, CV_8UC1);
  51. rng.fill(image, RNG::UNIFORM, 0, 256);
  52. }
  53. void LSDBase::GenerateConstColor(Mat& image)
  54. {
  55. image = Mat(img_size, CV_8UC1, Scalar::all(rng.uniform(0, 256)));
  56. }
  57. void LSDBase::GenerateLines(Mat& image, const unsigned int numLines)
  58. {
  59. image = Mat(img_size, CV_8UC1, Scalar::all(rng.uniform(0, 128)));
  60. for(unsigned int i = 0; i < numLines; ++i)
  61. {
  62. int y = rng.uniform(10, img_size.width - 10);
  63. Point p1(y, 10);
  64. Point p2(y, img_size.height - 10);
  65. line(image, p1, p2, Scalar(255), 3);
  66. }
  67. }
  68. void LSDBase::GenerateRotatedRect(Mat& image)
  69. {
  70. image = Mat::zeros(img_size, CV_8UC1);
  71. Point center(rng.uniform(img_size.width/4, img_size.width*3/4),
  72. rng.uniform(img_size.height/4, img_size.height*3/4));
  73. Size rect_size(rng.uniform(img_size.width/8, img_size.width/6),
  74. rng.uniform(img_size.height/8, img_size.height/6));
  75. float angle = rng.uniform(0.f, 360.f);
  76. Point2f vertices[4];
  77. RotatedRect rRect = RotatedRect(center, rect_size, angle);
  78. rRect.points(vertices);
  79. for (int i = 0; i < 4; i++)
  80. {
  81. line(image, vertices[i], vertices[(i + 1) % 4], Scalar(255), 3);
  82. }
  83. }
  84. void LSDBase::SetUp()
  85. {
  86. lines.clear();
  87. test_image = Mat();
  88. rng = RNG(LSD_TEST_SEED);
  89. passedtests = 0;
  90. }
  91. TEST_F(Imgproc_LSD_ADV, whiteNoise)
  92. {
  93. for (int i = 0; i < EPOCHS; ++i)
  94. {
  95. GenerateWhiteNoise(test_image);
  96. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_ADV);
  97. detector->detect(test_image, lines);
  98. if(40u >= lines.size()) ++passedtests;
  99. }
  100. ASSERT_EQ(EPOCHS, passedtests);
  101. }
  102. TEST_F(Imgproc_LSD_ADV, constColor)
  103. {
  104. for (int i = 0; i < EPOCHS; ++i)
  105. {
  106. GenerateConstColor(test_image);
  107. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_ADV);
  108. detector->detect(test_image, lines);
  109. if(0u == lines.size()) ++passedtests;
  110. }
  111. ASSERT_EQ(EPOCHS, passedtests);
  112. }
  113. TEST_F(Imgproc_LSD_ADV, lines)
  114. {
  115. for (int i = 0; i < EPOCHS; ++i)
  116. {
  117. const unsigned int numOfLines = 1;
  118. GenerateLines(test_image, numOfLines);
  119. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_ADV);
  120. detector->detect(test_image, lines);
  121. if(numOfLines * 2 == lines.size()) ++passedtests; // * 2 because of Gibbs effect
  122. }
  123. ASSERT_EQ(EPOCHS, passedtests);
  124. }
  125. TEST_F(Imgproc_LSD_ADV, rotatedRect)
  126. {
  127. for (int i = 0; i < EPOCHS; ++i)
  128. {
  129. GenerateRotatedRect(test_image);
  130. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_ADV);
  131. detector->detect(test_image, lines);
  132. if(2u <= lines.size()) ++passedtests;
  133. }
  134. ASSERT_EQ(EPOCHS, passedtests);
  135. }
  136. TEST_F(Imgproc_LSD_STD, whiteNoise)
  137. {
  138. for (int i = 0; i < EPOCHS; ++i)
  139. {
  140. GenerateWhiteNoise(test_image);
  141. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_STD);
  142. detector->detect(test_image, lines);
  143. if(50u >= lines.size()) ++passedtests;
  144. }
  145. ASSERT_EQ(EPOCHS, passedtests);
  146. }
  147. TEST_F(Imgproc_LSD_STD, constColor)
  148. {
  149. for (int i = 0; i < EPOCHS; ++i)
  150. {
  151. GenerateConstColor(test_image);
  152. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_STD);
  153. detector->detect(test_image, lines);
  154. if(0u == lines.size()) ++passedtests;
  155. }
  156. ASSERT_EQ(EPOCHS, passedtests);
  157. }
  158. TEST_F(Imgproc_LSD_STD, lines)
  159. {
  160. for (int i = 0; i < EPOCHS; ++i)
  161. {
  162. const unsigned int numOfLines = 1;
  163. GenerateLines(test_image, numOfLines);
  164. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_STD);
  165. detector->detect(test_image, lines);
  166. if(numOfLines * 2 == lines.size()) ++passedtests; // * 2 because of Gibbs effect
  167. }
  168. ASSERT_EQ(EPOCHS, passedtests);
  169. }
  170. TEST_F(Imgproc_LSD_STD, rotatedRect)
  171. {
  172. for (int i = 0; i < EPOCHS; ++i)
  173. {
  174. GenerateRotatedRect(test_image);
  175. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_STD);
  176. detector->detect(test_image, lines);
  177. if(4u <= lines.size()) ++passedtests;
  178. }
  179. ASSERT_EQ(EPOCHS, passedtests);
  180. }
  181. TEST_F(Imgproc_LSD_NONE, whiteNoise)
  182. {
  183. for (int i = 0; i < EPOCHS; ++i)
  184. {
  185. GenerateWhiteNoise(test_image);
  186. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_NONE);
  187. detector->detect(test_image, lines);
  188. if(50u >= lines.size()) ++passedtests;
  189. }
  190. ASSERT_EQ(EPOCHS, passedtests);
  191. }
  192. TEST_F(Imgproc_LSD_NONE, constColor)
  193. {
  194. for (int i = 0; i < EPOCHS; ++i)
  195. {
  196. GenerateConstColor(test_image);
  197. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_NONE);
  198. detector->detect(test_image, lines);
  199. if(0u == lines.size()) ++passedtests;
  200. }
  201. ASSERT_EQ(EPOCHS, passedtests);
  202. }
  203. TEST_F(Imgproc_LSD_NONE, lines)
  204. {
  205. for (int i = 0; i < EPOCHS; ++i)
  206. {
  207. const unsigned int numOfLines = 1;
  208. GenerateLines(test_image, numOfLines);
  209. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_NONE);
  210. detector->detect(test_image, lines);
  211. if(numOfLines * 2 == lines.size()) ++passedtests; // * 2 because of Gibbs effect
  212. }
  213. ASSERT_EQ(EPOCHS, passedtests);
  214. }
  215. TEST_F(Imgproc_LSD_NONE, rotatedRect)
  216. {
  217. for (int i = 0; i < EPOCHS; ++i)
  218. {
  219. GenerateRotatedRect(test_image);
  220. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_NONE);
  221. detector->detect(test_image, lines);
  222. if(8u <= lines.size()) ++passedtests;
  223. }
  224. ASSERT_EQ(EPOCHS, passedtests);
  225. }
  226. TEST_F(Imgproc_LSD_Common, supportsVec4iResult)
  227. {
  228. for (int i = 0; i < EPOCHS; ++i)
  229. {
  230. GenerateWhiteNoise(test_image);
  231. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_STD);
  232. detector->detect(test_image, lines);
  233. std::vector<Vec4i> linesVec4i;
  234. detector->detect(test_image, linesVec4i);
  235. if (lines.size() == linesVec4i.size())
  236. {
  237. bool pass = true;
  238. for (size_t lineIndex = 0; pass && lineIndex < lines.size(); lineIndex++)
  239. {
  240. for (int ch = 0; ch < 4; ch++)
  241. {
  242. if (cv::saturate_cast<int>(lines[lineIndex][ch]) != linesVec4i[lineIndex][ch])
  243. {
  244. pass = false;
  245. break;
  246. }
  247. }
  248. }
  249. if (pass)
  250. ++passedtests;
  251. }
  252. }
  253. ASSERT_EQ(EPOCHS, passedtests);
  254. }
  255. TEST_F(Imgproc_LSD_Common, drawSegmentsVec4f)
  256. {
  257. GenerateConstColor(test_image);
  258. std::vector<Vec4f> linesVec4f;
  259. RNG cr(0); // constant seed for deterministic test
  260. for (int j = 0; j < 10; j++) {
  261. linesVec4f.push_back(
  262. Vec4f(float(cr) * test_image.cols, float(cr) * test_image.rows, float(cr) * test_image.cols, float(cr) * test_image.rows));
  263. }
  264. Mat actual = Mat::zeros(test_image.size(), CV_8UC3);
  265. Mat expected = Mat::zeros(test_image.size(), CV_8UC3);
  266. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_STD);
  267. detector->drawSegments(actual, linesVec4f);
  268. // something should be drawn
  269. ASSERT_EQ(sum(actual == expected) != Scalar::all(0), true);
  270. for (size_t lineIndex = 0; lineIndex < linesVec4f.size(); lineIndex++)
  271. {
  272. const Vec4f &v = linesVec4f[lineIndex];
  273. const Point2f b(v[0], v[1]);
  274. const Point2f e(v[2], v[3]);
  275. line(expected, b, e, Scalar(0, 0, 255), 1);
  276. }
  277. ASSERT_EQ(sum(actual != expected) == Scalar::all(0), true);
  278. }
  279. TEST_F(Imgproc_LSD_Common, drawSegmentsVec4i)
  280. {
  281. GenerateConstColor(test_image);
  282. std::vector<Vec4i> linesVec4i;
  283. RNG cr(0); // constant seed for deterministic test
  284. for (int j = 0; j < 10; j++) {
  285. linesVec4i.push_back(
  286. Vec4i(cr(test_image.cols), cr(test_image.rows), cr(test_image.cols), cr(test_image.rows)));
  287. }
  288. Mat actual = Mat::zeros(test_image.size(), CV_8UC3);
  289. Mat expected = Mat::zeros(test_image.size(), CV_8UC3);
  290. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_STD);
  291. detector->drawSegments(actual, linesVec4i);
  292. // something should be drawn
  293. ASSERT_EQ(sum(actual == expected) != Scalar::all(0), true);
  294. for (size_t lineIndex = 0; lineIndex < linesVec4i.size(); lineIndex++)
  295. {
  296. const Vec4f &v = linesVec4i[lineIndex];
  297. const Point2f b(v[0], v[1]);
  298. const Point2f e(v[2], v[3]);
  299. line(expected, b, e, Scalar(0, 0, 255), 1);
  300. }
  301. ASSERT_EQ(sum(actual != expected) == Scalar::all(0), true);
  302. }
  303. TEST_F(Imgproc_LSD_Common, compareSegmentsVec4f)
  304. {
  305. GenerateConstColor(test_image);
  306. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_STD);
  307. std::vector<Vec4f> lines1, lines2;
  308. lines1.push_back(Vec4f(0, 0, 100, 200));
  309. lines2.push_back(Vec4f(0, 0, 100, 200));
  310. int result1 = detector->compareSegments(test_image.size(), lines1, lines2);
  311. ASSERT_EQ(result1, 0);
  312. lines2.push_back(Vec4f(100, 100, 110, 100));
  313. int result2 = detector->compareSegments(test_image.size(), lines1, lines2);
  314. ASSERT_EQ(result2, 11);
  315. }
  316. TEST_F(Imgproc_LSD_Common, compareSegmentsVec4i)
  317. {
  318. GenerateConstColor(test_image);
  319. Ptr<LineSegmentDetector> detector = createLineSegmentDetector(LSD_REFINE_STD);
  320. std::vector<Vec4i> lines1, lines2;
  321. lines1.push_back(Vec4i(0, 0, 100, 200));
  322. lines2.push_back(Vec4i(0, 0, 100, 200));
  323. int result1 = detector->compareSegments(test_image.size(), lines1, lines2);
  324. ASSERT_EQ(result1, 0);
  325. lines2.push_back(Vec4i(100, 100, 110, 100));
  326. int result2 = detector->compareSegments(test_image.size(), lines1, lines2);
  327. ASSERT_EQ(result2, 11);
  328. }
  329. }} // namespace