|
| 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 | +#include "opencv2/objdetect/aruco_detector.hpp" |
| 7 | + |
| 8 | +namespace opencv_test { namespace { |
| 9 | + |
| 10 | + |
| 11 | +TEST(CV_ArucoTutorial, can_find_singlemarkersoriginal) |
| 12 | +{ |
| 13 | + string img_path = cvtest::findDataFile("singlemarkersoriginal.jpg", false); |
| 14 | + Mat image = imread(img_path); |
| 15 | + aruco::ArucoDetector detector(aruco::getPredefinedDictionary(aruco::DICT_6X6_250)); |
| 16 | + |
| 17 | + vector<int> ids; |
| 18 | + vector<vector<Point2f> > corners, rejected; |
| 19 | + const size_t N = 6ull; |
| 20 | + // corners of ArUco markers with indices goldCornersIds |
| 21 | + const int goldCorners[N][8] = { {359,310, 404,310, 410,350, 362,350}, {427,255, 469,256, 477,289, 434,288}, |
| 22 | + {233,273, 190,273, 196,241, 237,241}, {298,185, 334,186, 335,212, 297,211}, |
| 23 | + {425,163, 430,186, 394,186, 390,162}, {195,155, 230,155, 227,178, 190,178} }; |
| 24 | + const int goldCornersIds[N] = { 40, 98, 62, 23, 124, 203}; |
| 25 | + map<int, const int*> mapGoldCorners; |
| 26 | + for (size_t i = 0; i < N; i++) |
| 27 | + mapGoldCorners[goldCornersIds[i]] = goldCorners[i]; |
| 28 | + |
| 29 | + detector.detectMarkers(image, corners, ids, rejected); |
| 30 | + |
| 31 | + ASSERT_EQ(N, ids.size()); |
| 32 | + for (size_t i = 0; i < N; i++) |
| 33 | + { |
| 34 | + int arucoId = ids[i]; |
| 35 | + ASSERT_EQ(4ull, corners[i].size()); |
| 36 | + ASSERT_TRUE(mapGoldCorners.find(arucoId) != mapGoldCorners.end()); |
| 37 | + for (int j = 0; j < 4; j++) |
| 38 | + { |
| 39 | + EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j * 2]), corners[i][j].x, 1.f); |
| 40 | + EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j * 2 + 1]), corners[i][j].y, 1.f); |
| 41 | + } |
| 42 | + } |
| 43 | +} |
| 44 | + |
| 45 | +TEST(CV_ArucoTutorial, can_find_gboriginal) |
| 46 | +{ |
| 47 | + string imgPath = cvtest::findDataFile("gboriginal.png", false); |
| 48 | + Mat image = imread(imgPath); |
| 49 | + string dictPath = cvtest::findDataFile("tutorial_dict.yml", false); |
| 50 | + Ptr<aruco::Dictionary> dictionary = makePtr<aruco::Dictionary>(); |
| 51 | + |
| 52 | + FileStorage fs(dictPath, FileStorage::READ); |
| 53 | + dictionary->aruco::Dictionary::readDictionary(fs.root()); // set marker from tutorial_dict.yml |
| 54 | + Ptr<aruco::DetectorParameters> detectorParams = aruco::DetectorParameters::create(); |
| 55 | + |
| 56 | + aruco::ArucoDetector detector(dictionary, detectorParams); |
| 57 | + |
| 58 | + vector<int> ids; |
| 59 | + vector<vector<Point2f> > corners, rejected; |
| 60 | + const size_t N = 35ull; |
| 61 | + // corners of ArUco markers with indices 0, 1, ..., 34 |
| 62 | + const int goldCorners[N][8] = { {252,74, 286,81, 274,102, 238,95}, {295,82, 330,89, 319,111, 282,104}, |
| 63 | + {338,91, 375,99, 365,121, 327,113}, {383,100, 421,107, 412,130, 374,123}, |
| 64 | + {429,109, 468,116, 461,139, 421,132}, {235,100, 270,108, 257,130, 220,122}, |
| 65 | + {279,109, 316,117, 304,140, 266,133}, {324,119, 362,126, 352,150, 313,143}, |
| 66 | + {371,128, 410,136, 400,161, 360,152}, {418,139, 459,145, 451,170, 410,163}, |
| 67 | + {216,128, 253,136, 239,161, 200,152}, {262,138, 300,146, 287,172, 248,164}, |
| 68 | + {309,148, 349,156, 337,183, 296,174}, {358,158, 398,167, 388,194, 346,185}, |
| 69 | + {407,169, 449,176, 440,205, 397,196}, {196,158, 235,168, 218,195, 179,185}, |
| 70 | + {243,170, 283,178, 269,206, 228,197}, {293,180, 334,190, 321,218, 279,209}, |
| 71 | + {343,192, 385,200, 374,230, 330,220}, {395,203, 438,211, 429,241, 384,233}, |
| 72 | + {174,192, 215,201, 197,231, 156,221}, {223,204, 265,213, 249,244, 207,234}, |
| 73 | + {275,215, 317,225, 303,257, 259,246}, {327,227, 371,238, 359,270, 313,259}, |
| 74 | + {381,240, 426,249, 416,282, 369,273}, {151,228, 193,238, 173,271, 130,260}, |
| 75 | + {202,241, 245,251, 228,285, 183,274}, {255,254, 300,264, 284,299, 238,288}, |
| 76 | + {310,267, 355,278, 342,314, 295,302}, {366,281, 413,290, 402,327, 353,317}, |
| 77 | + {125,267, 168,278, 147,314, 102,303}, {178,281, 223,293, 204,330, 157,317}, |
| 78 | + {233,296, 280,307, 263,346, 214,333}, {291,310, 338,322, 323,363, 274,349}, |
| 79 | + {349,325, 399,336, 386,378, 335,366} }; |
| 80 | + map<int, const int*> mapGoldCorners; |
| 81 | + for (int i = 0; i < static_cast<int>(N); i++) |
| 82 | + mapGoldCorners[i] = goldCorners[i]; |
| 83 | + |
| 84 | + detector.detectMarkers(image, corners, ids, rejected); |
| 85 | + |
| 86 | + ASSERT_EQ(N, ids.size()); |
| 87 | + for (size_t i = 0; i < N; i++) |
| 88 | + { |
| 89 | + int arucoId = ids[i]; |
| 90 | + ASSERT_EQ(4ull, corners[i].size()); |
| 91 | + ASSERT_TRUE(mapGoldCorners.find(arucoId) != mapGoldCorners.end()); |
| 92 | + for (int j = 0; j < 4; j++) |
| 93 | + { |
| 94 | + EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j*2]), corners[i][j].x, 1.f); |
| 95 | + EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j*2+1]), corners[i][j].y, 1.f); |
| 96 | + } |
| 97 | + } |
| 98 | +} |
| 99 | + |
| 100 | +TEST(CV_ArucoTutorial, can_find_choriginal) |
| 101 | +{ |
| 102 | + string imgPath = cvtest::findDataFile("choriginal.jpg", false); |
| 103 | + Mat image = imread(imgPath); |
| 104 | + aruco::ArucoDetector detector(aruco::getPredefinedDictionary(aruco::DICT_6X6_250)); |
| 105 | + |
| 106 | + vector< int > ids; |
| 107 | + vector< vector< Point2f > > corners, rejected; |
| 108 | + const size_t N = 17ull; |
| 109 | + // corners of aruco markers with indices goldCornersIds |
| 110 | + const int goldCorners[N][8] = { {268,77, 290,80, 286,97, 263,94}, {360,90, 382,93, 379,111, 357,108}, |
| 111 | + {211,106, 233,109, 228,127, 205,123}, {306,120, 328,124, 325,142, 302,138}, |
| 112 | + {402,135, 425,139, 423,157, 400,154}, {247,152, 271,155, 267,174, 242,171}, |
| 113 | + {347,167, 371,171, 369,191, 344,187}, {185,185, 209,189, 203,210, 178,206}, |
| 114 | + {288,201, 313,206, 309,227, 284,223}, {393,218, 418,222, 416,245, 391,241}, |
| 115 | + {223,240, 250,244, 244,268, 217,263}, {333,258, 359,262, 356,286, 329,282}, |
| 116 | + {152,281, 179,285, 171,312, 143,307}, {267,300, 294,305, 289,331, 261,327}, |
| 117 | + {383,319, 410,324, 408,351, 380,347}, {194,347, 223,352, 216,382, 186,377}, |
| 118 | + {315,368, 345,373, 341,403, 310,398} }; |
| 119 | + map<int, const int*> mapGoldCorners; |
| 120 | + for (int i = 0; i < static_cast<int>(N); i++) |
| 121 | + mapGoldCorners[i] = goldCorners[i]; |
| 122 | + |
| 123 | + detector.detectMarkers(image, corners, ids, rejected); |
| 124 | + |
| 125 | + ASSERT_EQ(N, ids.size()); |
| 126 | + for (size_t i = 0; i < N; i++) |
| 127 | + { |
| 128 | + int arucoId = ids[i]; |
| 129 | + ASSERT_EQ(4ull, corners[i].size()); |
| 130 | + ASSERT_TRUE(mapGoldCorners.find(arucoId) != mapGoldCorners.end()); |
| 131 | + for (int j = 0; j < 4; j++) |
| 132 | + { |
| 133 | + EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j * 2]), corners[i][j].x, 1.f); |
| 134 | + EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j * 2 + 1]), corners[i][j].y, 1.f); |
| 135 | + } |
| 136 | + } |
| 137 | +} |
| 138 | + |
| 139 | +TEST(CV_ArucoTutorial, can_find_chocclusion) |
| 140 | +{ |
| 141 | + string imgPath = cvtest::findDataFile("chocclusion_original.jpg", false); |
| 142 | + Mat image = imread(imgPath); |
| 143 | + aruco::ArucoDetector detector(aruco::getPredefinedDictionary(aruco::DICT_6X6_250)); |
| 144 | + |
| 145 | + vector< int > ids; |
| 146 | + vector< vector< Point2f > > corners, rejected; |
| 147 | + const size_t N = 13ull; |
| 148 | + // corners of aruco markers with indices goldCornersIds |
| 149 | + const int goldCorners[N][8] = { {301,57, 322,62, 317,79, 295,73}, {391,80, 413,85, 408,103, 386,97}, |
| 150 | + {242,79, 264,85, 256,102, 234,96}, {334,103, 357,109, 352,126, 329,121}, |
| 151 | + {428,129, 451,134, 448,152, 425,146}, {274,128, 296,134, 290,153, 266,147}, |
| 152 | + {371,154, 394,160, 390,180, 366,174}, {208,155, 232,161, 223,181, 199,175}, |
| 153 | + {309,182, 333,188, 327,209, 302,203}, {411,210, 436,216, 432,238, 407,231}, |
| 154 | + {241,212, 267,219, 258,242, 232,235}, {167,244, 194,252, 183,277, 156,269}, |
| 155 | + {202,314, 230,322, 220,349, 191,341} }; |
| 156 | + map<int, const int*> mapGoldCorners; |
| 157 | + const int goldCornersIds[N] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15}; |
| 158 | + for (int i = 0; i < static_cast<int>(N); i++) |
| 159 | + mapGoldCorners[goldCornersIds[i]] = goldCorners[i]; |
| 160 | + |
| 161 | + detector.detectMarkers(image, corners, ids, rejected); |
| 162 | + |
| 163 | + ASSERT_EQ(N, ids.size()); |
| 164 | + for (size_t i = 0; i < N; i++) |
| 165 | + { |
| 166 | + int arucoId = ids[i]; |
| 167 | + ASSERT_EQ(4ull, corners[i].size()); |
| 168 | + ASSERT_TRUE(mapGoldCorners.find(arucoId) != mapGoldCorners.end()); |
| 169 | + for (int j = 0; j < 4; j++) |
| 170 | + { |
| 171 | + EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j * 2]), corners[i][j].x, 1.f); |
| 172 | + EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j * 2 + 1]), corners[i][j].y, 1.f); |
| 173 | + } |
| 174 | + } |
| 175 | +} |
| 176 | + |
| 177 | +TEST(CV_ArucoTutorial, can_find_diamondmarkers) |
| 178 | +{ |
| 179 | + string imgPath = cvtest::findDataFile("diamondmarkers.png", false); |
| 180 | + Mat image = imread(imgPath); |
| 181 | + |
| 182 | + string dictPath = cvtest::findDataFile("tutorial_dict.yml", false); |
| 183 | + Ptr<aruco::Dictionary> dictionary = makePtr<aruco::Dictionary>(); |
| 184 | + FileStorage fs(dictPath, FileStorage::READ); |
| 185 | + dictionary->aruco::Dictionary::readDictionary(fs.root()); // set marker from tutorial_dict.yml |
| 186 | + |
| 187 | + string detectorPath = cvtest::findDataFile("detector_params.yml", false); |
| 188 | + fs = FileStorage(detectorPath, FileStorage::READ); |
| 189 | + Ptr<aruco::DetectorParameters> detectorParams = aruco::DetectorParameters::create(); |
| 190 | + detectorParams->readDetectorParameters(fs.root()); |
| 191 | + detectorParams->cornerRefinementMethod = 3; |
| 192 | + |
| 193 | + aruco::ArucoDetector detector(dictionary, detectorParams); |
| 194 | + |
| 195 | + vector< int > ids; |
| 196 | + vector< vector< Point2f > > corners, rejected; |
| 197 | + const size_t N = 12ull; |
| 198 | + // corner indices of ArUco markers |
| 199 | + const int goldCornersIds[N] = { 4, 12, 11, 3, 12, 10, 12, 10, 10, 11, 2, 11 }; |
| 200 | + map<int, int> counterGoldCornersIds; |
| 201 | + for (int i = 0; i < static_cast<int>(N); i++) |
| 202 | + counterGoldCornersIds[goldCornersIds[i]]++; |
| 203 | + |
| 204 | + detector.detectMarkers(image, corners, ids, rejected); |
| 205 | + map<int, int> counterRes; |
| 206 | + for (size_t i = 0; i < N; i++) |
| 207 | + { |
| 208 | + int arucoId = ids[i]; |
| 209 | + counterRes[arucoId]++; |
| 210 | + } |
| 211 | + |
| 212 | + ASSERT_EQ(N, ids.size()); |
| 213 | + EXPECT_EQ(counterGoldCornersIds, counterRes); // check the number of ArUco markers |
| 214 | +} |
| 215 | + |
| 216 | +}} // namespace |
0 commit comments