test_intelligent_scissors.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  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. //#include "opencv2/imgproc/segmentation.hpp"
  6. namespace opencv_test { namespace {
  7. Mat getTestImageGray()
  8. {
  9. static Mat m;
  10. if (m.empty())
  11. {
  12. m = imread(findDataFile("shared/lena.png"), IMREAD_GRAYSCALE);
  13. }
  14. return m.clone();
  15. }
  16. Mat getTestImageColor()
  17. {
  18. static Mat m;
  19. if (m.empty())
  20. {
  21. m = imread(findDataFile("shared/lena.png"), IMREAD_COLOR);
  22. }
  23. return m.clone();
  24. }
  25. Mat getTestImage1()
  26. {
  27. static Mat m;
  28. if (m.empty())
  29. {
  30. m.create(Size(200, 100), CV_8UC1);
  31. m.setTo(Scalar::all(128));
  32. Rect roi(50, 30, 100, 40);
  33. m(roi).setTo(Scalar::all(0));
  34. #if 0
  35. imshow("image", m);
  36. waitKey();
  37. #endif
  38. }
  39. return m.clone();
  40. }
  41. Mat getTestImage2()
  42. {
  43. static Mat m;
  44. if (m.empty())
  45. {
  46. m.create(Size(200, 100), CV_8UC1);
  47. m.setTo(Scalar::all(128));
  48. Rect roi(40, 30, 100, 40);
  49. m(roi).setTo(Scalar::all(255));
  50. #if 0
  51. imshow("image", m);
  52. waitKey();
  53. #endif
  54. }
  55. return m.clone();
  56. }
  57. Mat getTestImage3()
  58. {
  59. static Mat m;
  60. if (m.empty())
  61. {
  62. m.create(Size(200, 100), CV_8UC1);
  63. m.setTo(Scalar::all(128));
  64. Scalar color(0,0,0,0);
  65. line(m, Point(30, 50), Point(50, 50), color, 1);
  66. line(m, Point(50, 50), Point(80, 30), color, 1);
  67. line(m, Point(150, 50), Point(80, 30), color, 1);
  68. line(m, Point(150, 50), Point(180, 50), color, 1);
  69. line(m, Point(80, 10), Point(80, 90), Scalar::all(200), 1);
  70. line(m, Point(100, 10), Point(100, 90), Scalar::all(200), 1);
  71. line(m, Point(120, 10), Point(120, 90), Scalar::all(200), 1);
  72. #if 0
  73. imshow("image", m);
  74. waitKey();
  75. #endif
  76. }
  77. return m.clone();
  78. }
  79. Mat getTestImage4()
  80. {
  81. static Mat m;
  82. if (m.empty())
  83. {
  84. m.create(Size(200, 100), CV_8UC1);
  85. for (int y = 0; y < m.rows; y++)
  86. {
  87. for (int x = 0; x < m.cols; x++)
  88. {
  89. float dx = (float)(x - 100);
  90. float dy = (float)(y - 100);
  91. float d = sqrtf(dx * dx + dy * dy);
  92. m.at<uchar>(y, x) = saturate_cast<uchar>(100 + 100 * sin(d / 10 * CV_PI));
  93. }
  94. }
  95. #if 0
  96. imshow("image", m);
  97. waitKey();
  98. #endif
  99. }
  100. return m.clone();
  101. }
  102. Mat getTestImage5()
  103. {
  104. static Mat m;
  105. if (m.empty())
  106. {
  107. m.create(Size(200, 100), CV_8UC1);
  108. for (int y = 0; y < m.rows; y++)
  109. {
  110. for (int x = 0; x < m.cols; x++)
  111. {
  112. float dx = (float)(x - 100);
  113. float dy = (float)(y - 100);
  114. float d = sqrtf(dx * dx + dy * dy);
  115. m.at<uchar>(y, x) = saturate_cast<uchar>(x / 2 + 100 * sin(d / 10 * CV_PI));
  116. }
  117. }
  118. #if 0
  119. imshow("image", m);
  120. waitKey();
  121. #endif
  122. }
  123. return m.clone();
  124. }
  125. void show(const Mat& img, const std::vector<Point> pts)
  126. {
  127. if (cvtest::debugLevel >= 10)
  128. {
  129. Mat dst = img.clone();
  130. std::vector< std::vector<Point> > contours;
  131. contours.push_back(pts);
  132. polylines(dst, contours, false, Scalar::all(255));
  133. imshow("dst", dst);
  134. waitKey();
  135. }
  136. }
  137. TEST(Imgproc_IntelligentScissorsMB, rect)
  138. {
  139. segmentation::IntelligentScissorsMB tool;
  140. tool.applyImage(getTestImage1());
  141. Point source_point(50, 30);
  142. tool.buildMap(source_point);
  143. Point target_point(100, 30);
  144. std::vector<Point> pts;
  145. tool.getContour(target_point, pts);
  146. tool.applyImage(getTestImage2());
  147. tool.buildMap(source_point);
  148. std::vector<Point> pts2;
  149. tool.getContour(target_point, pts2, true/*backward*/);
  150. EXPECT_EQ(pts.size(), pts2.size());
  151. }
  152. TEST(Imgproc_IntelligentScissorsMB, lines)
  153. {
  154. segmentation::IntelligentScissorsMB tool;
  155. Mat image = getTestImage3();
  156. tool.applyImage(image);
  157. Point source_point(30, 50);
  158. tool.buildMap(source_point);
  159. Point target_point(150, 50);
  160. std::vector<Point> pts;
  161. tool.getContour(target_point, pts);
  162. EXPECT_EQ((size_t)121, pts.size());
  163. show(image, pts);
  164. }
  165. TEST(Imgproc_IntelligentScissorsMB, circles)
  166. {
  167. segmentation::IntelligentScissorsMB tool;
  168. tool.setGradientMagnitudeMaxLimit(10);
  169. Mat image = getTestImage4();
  170. tool.applyImage(image);
  171. Point source_point(50, 50);
  172. tool.buildMap(source_point);
  173. Point target_point(150, 50);
  174. std::vector<Point> pts;
  175. tool.getContour(target_point, pts);
  176. EXPECT_EQ((size_t)101, pts.size());
  177. show(image, pts);
  178. }
  179. TEST(Imgproc_IntelligentScissorsMB, circles_gradient)
  180. {
  181. segmentation::IntelligentScissorsMB tool;
  182. Mat image = getTestImage5();
  183. tool.applyImage(image);
  184. Point source_point(50, 50);
  185. tool.buildMap(source_point);
  186. Point target_point(150, 50);
  187. std::vector<Point> pts;
  188. tool.getContour(target_point, pts);
  189. EXPECT_EQ((size_t)101, pts.size());
  190. show(image, pts);
  191. }
  192. #define PTS_SIZE_EPS 2
  193. TEST(Imgproc_IntelligentScissorsMB, grayscale)
  194. {
  195. segmentation::IntelligentScissorsMB tool;
  196. Mat image = getTestImageGray();
  197. tool.applyImage(image);
  198. Point source_point(275, 63);
  199. tool.buildMap(source_point);
  200. Point target_point(413, 155);
  201. std::vector<Point> pts;
  202. tool.getContour(target_point, pts);
  203. size_t gold = 206;
  204. EXPECT_GE(pts.size(), gold - PTS_SIZE_EPS);
  205. EXPECT_LE(pts.size(), gold + PTS_SIZE_EPS);
  206. show(image, pts);
  207. }
  208. TEST(Imgproc_IntelligentScissorsMB, check_features_grayscale_1_0_0_zerro_crossing_with_limit)
  209. {
  210. segmentation::IntelligentScissorsMB tool;
  211. tool.setEdgeFeatureZeroCrossingParameters(64);
  212. tool.setWeights(1.0f, 0.0f, 0.0f);
  213. Mat image = getTestImageGray();
  214. tool.applyImage(image);
  215. Point source_point(275, 63);
  216. tool.buildMap(source_point);
  217. Point target_point(413, 155);
  218. std::vector<Point> pts;
  219. tool.getContour(target_point, pts);
  220. size_t gold = 207;
  221. EXPECT_GE(pts.size(), gold - PTS_SIZE_EPS);
  222. EXPECT_LE(pts.size(), gold + PTS_SIZE_EPS);
  223. show(image, pts);
  224. }
  225. TEST(Imgproc_IntelligentScissorsMB, check_features_grayscale_1_0_0_canny)
  226. {
  227. segmentation::IntelligentScissorsMB tool;
  228. tool.setEdgeFeatureCannyParameters(50, 100);
  229. tool.setWeights(1.0f, 0.0f, 0.0f);
  230. Mat image = getTestImageGray();
  231. tool.applyImage(image);
  232. Point source_point(275, 63);
  233. tool.buildMap(source_point);
  234. Point target_point(413, 155);
  235. std::vector<Point> pts;
  236. tool.getContour(target_point, pts);
  237. size_t gold = 201;
  238. EXPECT_GE(pts.size(), gold - PTS_SIZE_EPS);
  239. EXPECT_LE(pts.size(), gold + PTS_SIZE_EPS);
  240. show(image, pts);
  241. }
  242. TEST(Imgproc_IntelligentScissorsMB, check_features_grayscale_0_1_0)
  243. {
  244. segmentation::IntelligentScissorsMB tool;
  245. tool.setWeights(0.0f, 1.0f, 0.0f);
  246. Mat image = getTestImageGray();
  247. tool.applyImage(image);
  248. Point source_point(275, 63);
  249. tool.buildMap(source_point);
  250. Point target_point(413, 155);
  251. std::vector<Point> pts;
  252. tool.getContour(target_point, pts);
  253. size_t gold = 166;
  254. EXPECT_GE(pts.size(), gold - PTS_SIZE_EPS);
  255. EXPECT_LE(pts.size(), gold + PTS_SIZE_EPS);
  256. show(image, pts);
  257. }
  258. TEST(Imgproc_IntelligentScissorsMB, check_features_grayscale_0_0_1)
  259. {
  260. segmentation::IntelligentScissorsMB tool;
  261. tool.setWeights(0.0f, 0.0f, 1.0f);
  262. Mat image = getTestImageGray();
  263. tool.applyImage(image);
  264. Point source_point(275, 63);
  265. tool.buildMap(source_point);
  266. Point target_point(413, 155);
  267. std::vector<Point> pts;
  268. tool.getContour(target_point, pts);
  269. size_t gold = 197;
  270. EXPECT_GE(pts.size(), gold - PTS_SIZE_EPS);
  271. EXPECT_LE(pts.size(), gold + PTS_SIZE_EPS);
  272. show(image, pts);
  273. }
  274. TEST(Imgproc_IntelligentScissorsMB, color)
  275. {
  276. segmentation::IntelligentScissorsMB tool;
  277. Mat image = getTestImageColor();
  278. tool.applyImage(image);
  279. Point source_point(275, 63);
  280. tool.buildMap(source_point);
  281. Point target_point(413, 155);
  282. std::vector<Point> pts;
  283. tool.getContour(target_point, pts);
  284. size_t gold = 205;
  285. EXPECT_GE(pts.size(), gold - PTS_SIZE_EPS);
  286. EXPECT_LE(pts.size(), gold + PTS_SIZE_EPS);
  287. show(image, pts);
  288. }
  289. TEST(Imgproc_IntelligentScissorsMB, color_canny)
  290. {
  291. segmentation::IntelligentScissorsMB tool;
  292. tool.setEdgeFeatureCannyParameters(32, 100);
  293. Mat image = getTestImageColor();
  294. tool.applyImage(image);
  295. Point source_point(275, 63);
  296. tool.buildMap(source_point);
  297. Point target_point(413, 155);
  298. std::vector<Point> pts;
  299. tool.getContour(target_point, pts);
  300. size_t gold = 200;
  301. EXPECT_GE(pts.size(), gold - PTS_SIZE_EPS);
  302. EXPECT_LE(pts.size(), gold + PTS_SIZE_EPS);
  303. show(image, pts);
  304. }
  305. TEST(Imgproc_IntelligentScissorsMB, color_custom_features_invalid)
  306. {
  307. segmentation::IntelligentScissorsMB tool;
  308. ASSERT_ANY_THROW(tool.applyImageFeatures(noArray(), noArray(), noArray()));
  309. }
  310. TEST(Imgproc_IntelligentScissorsMB, color_custom_features_edge)
  311. {
  312. segmentation::IntelligentScissorsMB tool;
  313. Mat image = getTestImageColor();
  314. Mat canny_edges;
  315. Canny(image, canny_edges, 32, 100, 5);
  316. Mat binary_edge_feature;
  317. cv::threshold(canny_edges, binary_edge_feature, 254, 1, THRESH_BINARY_INV);
  318. tool.applyImageFeatures(binary_edge_feature, noArray(), noArray(), image);
  319. Point source_point(275, 63);
  320. tool.buildMap(source_point);
  321. Point target_point(413, 155);
  322. std::vector<Point> pts;
  323. tool.getContour(target_point, pts);
  324. size_t gold = 201;
  325. EXPECT_GE(pts.size(), gold - PTS_SIZE_EPS);
  326. EXPECT_LE(pts.size(), gold + PTS_SIZE_EPS);
  327. show(image, pts);
  328. }
  329. TEST(Imgproc_IntelligentScissorsMB, color_custom_features_all)
  330. {
  331. segmentation::IntelligentScissorsMB tool;
  332. tool.setWeights(0.9f, 0.0f, 0.1f);
  333. Mat image = getTestImageColor();
  334. Mat canny_edges;
  335. Canny(image, canny_edges, 50, 100, 5);
  336. Mat binary_edge_feature; // 0, 1 values
  337. cv::threshold(canny_edges, binary_edge_feature, 254, 1, THRESH_BINARY_INV);
  338. Mat_<Point2f> gradient_direction(image.size(), Point2f(0, 0)); // normalized
  339. Mat_<float> gradient_magnitude(image.size(), 0); // cost function
  340. tool.applyImageFeatures(binary_edge_feature, gradient_direction, gradient_magnitude);
  341. Point source_point(275, 63);
  342. tool.buildMap(source_point);
  343. Point target_point(413, 155);
  344. std::vector<Point> pts;
  345. tool.getContour(target_point, pts);
  346. size_t gold = 201;
  347. EXPECT_GE(pts.size(), gold - PTS_SIZE_EPS);
  348. EXPECT_LE(pts.size(), gold + PTS_SIZE_EPS);
  349. show(image, pts);
  350. }
  351. TEST(Imgproc_IntelligentScissorsMB, color_custom_features_edge_magnitude)
  352. {
  353. segmentation::IntelligentScissorsMB tool;
  354. tool.setWeights(0.9f, 0.0f, 0.1f);
  355. Mat image = getTestImageColor();
  356. Mat canny_edges;
  357. Canny(image, canny_edges, 50, 100, 5);
  358. Mat binary_edge_feature; // 0, 1 values
  359. cv::threshold(canny_edges, binary_edge_feature, 254, 1, THRESH_BINARY_INV);
  360. Mat_<float> gradient_magnitude(image.size(), 0); // cost function
  361. tool.applyImageFeatures(binary_edge_feature, noArray(), gradient_magnitude);
  362. Point source_point(275, 63);
  363. tool.buildMap(source_point);
  364. Point target_point(413, 155);
  365. std::vector<Point> pts;
  366. tool.getContour(target_point, pts);
  367. size_t gold = 201;
  368. EXPECT_GE(pts.size(), gold - PTS_SIZE_EPS);
  369. EXPECT_LE(pts.size(), gold + PTS_SIZE_EPS);
  370. show(image, pts);
  371. }
  372. }} // namespace