66namespace opencv_test {
77using namespace perf ;
88
9- typedef tuple<bool , int > ArucoTestParams ;
10- typedef TestBaseWithParam<ArucoTestParams > EstimateAruco;
9+ typedef tuple<bool , int > UseArucoParams ;
10+ typedef TestBaseWithParam<UseArucoParams > EstimateAruco;
1111#define ESTIMATE_PARAMS Combine (Values(false , true ), Values(-1 ))
1212
1313static double deg2rad(double deg) { return deg * CV_PI / 180 .; }
1414
1515class MarkerPainter
1616{
1717private:
18- int imgMarkerSize;
18+ int imgMarkerSize = 0 ;
1919 Mat cameraMatrix;
2020public:
2121 MarkerPainter (const int size)
@@ -28,8 +28,8 @@ class MarkerPainter
2828 imgMarkerSize = size;
2929 cameraMatrix = Mat::eye (3 , 3 , CV_64FC1);
3030 cameraMatrix.at <double >(0 , 0 ) = cameraMatrix.at <double >(1 , 1 ) = imgMarkerSize;
31- cameraMatrix.at <double >(0 , 2 ) = imgMarkerSize / 2 ;
32- cameraMatrix.at <double >(1 , 2 ) = imgMarkerSize / 2 ;
31+ cameraMatrix.at <double >(0 , 2 ) = imgMarkerSize / 2.0 ;
32+ cameraMatrix.at <double >(1 , 2 ) = imgMarkerSize / 2.0 ;
3333 }
3434
3535 static std::pair<Mat, Mat> getSyntheticRT (double yaw, double pitch, double distance)
@@ -99,20 +99,20 @@ class MarkerPainter
9999
100100 const float markerLength = 0 .05f ;
101101 vector<Point3f> markerObjPoints;
102- markerObjPoints.push_back (Point3f (-markerLength / 2 .f , +markerLength / 2 .f , 0 ));
103- markerObjPoints.push_back (markerObjPoints[0 ] + Point3f (markerLength, 0 , 0 ));
104- markerObjPoints.push_back (markerObjPoints[0 ] + Point3f (markerLength, -markerLength, 0 ));
105- markerObjPoints.push_back (markerObjPoints[0 ] + Point3f (0 , -markerLength, 0 ));
102+ markerObjPoints.emplace_back (Point3f (-markerLength / 2 .f , +markerLength / 2 .f , 0 ));
103+ markerObjPoints.emplace_back (markerObjPoints[0 ] + Point3f (markerLength, 0 , 0 ));
104+ markerObjPoints.emplace_back (markerObjPoints[0 ] + Point3f (markerLength, -markerLength, 0 ));
105+ markerObjPoints.emplace_back (markerObjPoints[0 ] + Point3f (0 , -markerLength, 0 ));
106106
107107 // project markers and draw them
108108 Mat distCoeffs (5 , 1 , CV_64FC1, Scalar::all (0 ));
109109 projectPoints (markerObjPoints, rvec, tvec, cameraMatrix, distCoeffs, corners);
110110
111111 vector<Point2f> originalCorners;
112- originalCorners.push_back (Point2f (0 .f , 0 .f ));
113- originalCorners.push_back (originalCorners[0 ]+Point2f ((float )markerSizePixels, 0 ));
114- originalCorners.push_back (originalCorners[0 ]+Point2f ((float )markerSizePixels, (float )markerSizePixels));
115- originalCorners.push_back (originalCorners[0 ]+Point2f (0 , (float )markerSizePixels));
112+ originalCorners.emplace_back (Point2f (0 .f , 0 .f ));
113+ originalCorners.emplace_back (originalCorners[0 ]+Point2f ((float )markerSizePixels, 0 ));
114+ originalCorners.emplace_back (originalCorners[0 ]+Point2f ((float )markerSizePixels, (float )markerSizePixels));
115+ originalCorners.emplace_back (originalCorners[0 ]+Point2f (0 , (float )markerSizePixels));
116116
117117 Mat transformation = getPerspectiveTransform (originalCorners, corners);
118118
@@ -135,12 +135,12 @@ class MarkerPainter
135135 {
136136 int currentId = iter;
137137 auto marker_corners = getProjectMarker (currentId, deg2rad (70 +yaw), deg2rad (pitch), params, dictionary);
138- Point2f startPoint (j*imgMarkerSize, i*imgMarkerSize);
138+ Point2i startPoint (j*imgMarkerSize, i*imgMarkerSize);
139139 Mat tmp_roi = tileImage (Rect (startPoint.x , startPoint.y , imgMarkerSize, imgMarkerSize));
140140 marker_corners.first .copyTo (tmp_roi);
141141
142142 for (Point2f& point: marker_corners.second )
143- point += startPoint;
143+ point += static_cast <Point2f>( startPoint) ;
144144 idCorners[currentId] = marker_corners.second ;
145145 auto test = idCorners[currentId];
146146 yaw = (yaw + 10 ) % 51 ; // 70+yaw >= 70 && 70+yaw <= 120
@@ -152,9 +152,27 @@ class MarkerPainter
152152 }
153153};
154154
155+ static inline vector<double > getDistanceVector (map<int , vector<Point2f> > &golds, const vector<int >& ids,
156+ const vector<vector<Point2f> >& corners)
157+ {
158+ vector<double > distVector (ids.size (), numeric_limits<double >::max ());
159+ for (size_t i = 0 ; i < ids.size (); i++)
160+ {
161+ int id = ids[i];
162+ const auto gold_corners = golds.find (id);
163+ if (gold_corners != golds.end ())
164+ for (int c = 0 ; c < 4 ; c++)
165+ {
166+ double distance = cv::norm (gold_corners->second [c] - corners[i][c]);
167+ distVector[i] = distance;
168+ }
169+ }
170+ return distVector;
171+ }
172+
155173PERF_TEST_P (EstimateAruco, ArucoFirst, ESTIMATE_PARAMS)
156174{
157- ArucoTestParams testParams = GetParam ();
175+ UseArucoParams testParams = GetParam ();
158176 Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary (aruco::DICT_6X6_250);
159177 Ptr<aruco::DetectorParameters> detectorParams = aruco::DetectorParameters::create ();
160178 detectorParams->minDistanceToBorder = 1 ;
@@ -180,22 +198,13 @@ PERF_TEST_P(EstimateAruco, ArucoFirst, ESTIMATE_PARAMS)
180198 aruco::detectMarkers (image_map.first , dictionary, corners, ids, detectorParams);
181199 }
182200 ASSERT_EQ (numMarkersInRow*numMarkersInRow, ids.size ());
183- for (size_t i = 0 ; i < ids.size (); i++)
184- {
185- int id = ids[i];
186- for (int c = 0 ; c < 4 ; c++)
187- {
188- std::vector<Point2f> test = image_map.second [id];
189- double dist = cv::norm (image_map.second [id][c] - corners[i][c]);
190- EXPECT_LE (dist, 5.0 );
191- }
192- }
193- SANITY_CHECK_NOTHING ();
201+ auto distVector = getDistanceVector (image_map.second , ids, corners);
202+ SANITY_CHECK (distVector, 3.0 *4.0 , ERROR_ABSOLUTE);
194203}
195204
196205PERF_TEST_P (EstimateAruco, ArucoSecond, ESTIMATE_PARAMS)
197206{
198- ArucoTestParams testParams = GetParam ();
207+ UseArucoParams testParams = GetParam ();
199208 Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary (aruco::DICT_6X6_250);
200209 Ptr<aruco::DetectorParameters> detectorParams = aruco::DetectorParameters::create ();
201210 detectorParams->minDistanceToBorder = 1 ;
@@ -221,41 +230,50 @@ PERF_TEST_P(EstimateAruco, ArucoSecond, ESTIMATE_PARAMS)
221230 aruco::detectMarkers (image_map.first , dictionary, corners, ids, detectorParams);
222231 }
223232 ASSERT_EQ (numMarkersInRow*numMarkersInRow, ids.size ());
224- for (size_t i = 0 ; i < ids.size (); i++)
233+ auto distVector = getDistanceVector (image_map.second , ids, corners);
234+ SANITY_CHECK (distVector, 3.0 *4.0 , ERROR_ABSOLUTE);
235+ }
236+
237+ struct Aruco3Params
238+ {
239+ bool useAruco3Detection = false ;
240+ float minMarkerLengthRatioOriginalImg = 0 .f;
241+ int minSideLengthCanonicalImg = 0 ;
242+
243+ Aruco3Params (bool useAruco3, float minMarkerLen, int minSideLen): useAruco3Detection(useAruco3),
244+ minMarkerLengthRatioOriginalImg (minMarkerLen),
245+ minSideLengthCanonicalImg(minSideLen) {}
246+ friend std::ostream& operator <<(std::ostream& os, const Aruco3Params& d)
225247 {
226- int id = ids[i];
227- for (int c = 0 ; c < 4 ; c++)
228- {
229- std::vector<Point2f> test = image_map.second [id];
230- double dist = cv::norm (image_map.second [id][c] - corners[i][c]);
231- EXPECT_LE (dist, 5.0 );
232- }
248+ os << d.useAruco3Detection << " " << d.minMarkerLengthRatioOriginalImg << " " << d.minSideLengthCanonicalImg ;
249+ return os;
233250 }
234- SANITY_CHECK_NOTHING () ;
235- }
251+ } ;
252+ typedef tuple<Aruco3Params, pair< int , int >> ArucoTestParams;
236253
237- typedef tuple<tuple<bool , float >, int > ArucoLargeTestParams;
238- typedef TestBaseWithParam<ArucoLargeTestParams> EstimateLargeAruco;
239- #define ESTIMATE_LARGE_PARAMS Combine (Values(make_tuple(false , 0 .f), make_tuple(true , 0 .015f )), Values(-1 ))
254+ typedef TestBaseWithParam<ArucoTestParams> EstimateLargeAruco;
255+ #define ESTIMATE_FHD_PARAMS Combine (Values(Aruco3Params(false , 0 .f, 0 ), Aruco3Params(true , 0 .f, 32 ), \
256+ Aruco3Params(true , 0 .015f , 32 ), Aruco3Params(true , 0 .f, 16 ), Aruco3Params(true , 0.008 , 16 )), \
257+ Values(std::make_pair(1440 , 1 ), std::make_pair(480 , 3 ), std::make_pair(144 , 10 )))
240258
241- PERF_TEST_P(EstimateLargeAruco, ArucoFHD, ESTIMATE_LARGE_PARAMS )
259+ PERF_TEST_P(EstimateLargeAruco, ArucoFHD, ESTIMATE_FHD_PARAMS )
242260{
243- ArucoLargeTestParams testParams = GetParam ();
261+ ArucoTestParams testParams = GetParam ();
244262 Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary (aruco::DICT_6X6_250);
245263 Ptr<aruco::DetectorParameters> detectorParams = aruco::DetectorParameters::create ();
246264 detectorParams->minDistanceToBorder = 1 ;
247265 detectorParams->markerBorderBits = 1 ;
248266 detectorParams->cornerRefinementMethod = cv::aruco::CORNER_REFINE_SUBPIX;
249267
250268 // USE_ARUCO3
251- detectorParams->useAruco3Detection = get<0 >(get< 0 >( testParams)) ;
269+ detectorParams->useAruco3Detection = get<0 >(testParams). useAruco3Detection ;
252270 if (detectorParams->useAruco3Detection ) {
253- detectorParams->minSideLengthCanonicalImg = 32 ;
254- detectorParams->minMarkerLengthRatioOriginalImg = get<1 >(get< 0 >(testParams)) ;
271+ detectorParams->minSideLengthCanonicalImg = get< 0 >(testParams). minSideLengthCanonicalImg ;
272+ detectorParams->minMarkerLengthRatioOriginalImg = get<0 >(testParams). minMarkerLengthRatioOriginalImg ;
255273 }
256- const int markerSize = 144 ;
257- const size_t numMarkersInRow = 10 ; // 1440*1440 = 1920*1080
258- MarkerPainter painter (markerSize);
274+ const int markerSize = get< 1 >(testParams). first ; // 1440 or 480 or 144
275+ const int numMarkersInRow = get< 1 >(testParams). second ; // 1 or 3 or 144
276+ MarkerPainter painter (markerSize); // num pixels is 1440x1440 as in FHD 1920x1080
259277 auto image_map = painter.getProjectMarkersTile (numMarkersInRow, detectorParams, dictionary);
260278
261279 // detect markers
@@ -265,78 +283,9 @@ PERF_TEST_P(EstimateLargeAruco, ArucoFHD, ESTIMATE_LARGE_PARAMS)
265283 {
266284 aruco::detectMarkers (image_map.first , dictionary, corners, ids, detectorParams);
267285 }
268- ASSERT_EQ (numMarkersInRow*numMarkersInRow, ids.size ());
269- for (size_t i = 0 ; i < ids.size (); i++)
270- {
271- int id = ids[i];
272- for (int c = 0 ; c < 4 ; c++)
273- {
274- std::vector<Point2f> test = image_map.second [id];
275- double dist = cv::norm (image_map.second [id][c] - corners[i][c]);
276- EXPECT_LE (dist, 5.0 );
277- }
278- }
279- SANITY_CHECK_NOTHING ();
280- }
281-
282- // TODO: delete this test
283- TEST (EstimateAruco, ArucoTryTest)
284- {
285- Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary (aruco::DICT_6X6_250);
286- Ptr<aruco::DetectorParameters> params = aruco::DetectorParameters::create ();
287- params->minDistanceToBorder = 1 ;
288-
289- // USE_ARUCO3
290- params->useAruco3Detection = true ;
291- params->cornerRefinementMethod = cv::aruco::CORNER_REFINE_SUBPIX;
292- params->minSideLengthCanonicalImg = 16 ;
293- params->markerBorderBits = 1 ;
294- MarkerPainter painter (100 );
295- int iter = 0 ;
296- // detect from different positions
297- for (int pitch = 0 ; pitch < 360 ; pitch += 70 ) {
298- for (int yaw = 70 ; yaw <= 120 ; yaw += 40 ) {
299- int currentId = iter % 250 ;
300- auto marker_corners = painter.getProjectMarker (currentId, deg2rad (yaw), deg2rad (pitch), params, dictionary);
301-
302- // detect markers
303- vector<vector<Point2f> > corners;
304- vector<int > ids;
305- aruco::detectMarkers (marker_corners.first , dictionary, corners, ids, params);
306- // check results
307- ASSERT_EQ (1ull , ids.size ());
308- ASSERT_EQ (currentId, ids[0 ]);
309- for (int c = 0 ; c < 4 ; c++)
310- {
311- double dist = cv::norm (marker_corners.second [c] - corners[0 ][c]);
312- EXPECT_LE (dist, 5.0 );
313- }
314- iter++;
315- }
316- }
317- params->minMarkerLengthRatioOriginalImg = 0 .1f ;
318- iter = 0 ;
319- // detect from different positions
320- for (int pitch = 0 ; pitch < 360 ; pitch += 70 ) {
321- for (int yaw = 70 ; yaw <= 120 ; yaw += 40 ) {
322- int currentId = iter % 250 ;
323- auto marker_corners = painter.getProjectMarker (currentId, deg2rad (yaw), deg2rad (pitch), params, dictionary);
324-
325- // detect markers
326- vector<vector<Point2f> > corners;
327- vector<int > ids;
328- aruco::detectMarkers (marker_corners.first , dictionary, corners, ids, params);
329- // check results
330- ASSERT_EQ (1ull , ids.size ());
331- ASSERT_EQ (currentId, ids[0 ]);
332- for (int c = 0 ; c < 4 ; c++)
333- {
334- double dist = cv::norm (marker_corners.second [c] - corners[0 ][c]);
335- EXPECT_LE (dist, 5.0 );
336- }
337- iter++;
338- }
339- }
286+ ASSERT_EQ (numMarkersInRow*numMarkersInRow, static_cast <int >(ids.size ()));
287+ auto distVector = getDistanceVector (image_map.second , ids, corners);
288+ SANITY_CHECK (distVector, 3.0 *4.0 , ERROR_ABSOLUTE);
340289}
341290
342291}
0 commit comments