@@ -182,12 +182,29 @@ static void getSyntheticRT(double yaw, double pitch, double distance, Mat &rvec,
182
182
*/
183
183
static Mat projectMarker (Ptr<aruco::Dictionary> &dictionary, int id, Mat cameraMatrix, double yaw,
184
184
double pitch, double distance, Size imageSize, int markerBorder,
185
- vector< Point2f > &corners) {
185
+ vector< Point2f > &corners, int encloseMarker= 0 ) {
186
186
187
187
// canonical image
188
- Mat markerImg;
188
+ Mat marker, markerImg;
189
189
const int markerSizePixels = 100 ;
190
- aruco::drawMarker (dictionary, id, markerSizePixels, markerImg, markerBorder);
190
+
191
+ aruco::drawMarker (dictionary, id, markerSizePixels, marker, markerBorder);
192
+ marker.copyTo (markerImg);
193
+
194
+ if (encloseMarker){ // to enclose the marker
195
+ int enclose = int (marker.rows /4 );
196
+ markerImg = Mat::zeros (marker.rows +(2 *enclose), marker.cols +(enclose*2 ), CV_8UC1);
197
+
198
+ Mat field= markerImg.rowRange (int (enclose), int (markerImg.rows -enclose))
199
+ .colRange (int (0 ), int (markerImg.cols ));
200
+ field.setTo (255 );
201
+ field= markerImg.rowRange (int (0 ), int (markerImg.rows ))
202
+ .colRange (int (enclose), int (markerImg.cols -enclose));
203
+ field.setTo (255 );
204
+
205
+ field = markerImg (Rect (enclose,enclose,marker.rows ,marker.cols ));
206
+ marker.copyTo (field);
207
+ }
191
208
192
209
// get rvec and tvec for the perspective
193
210
Mat rvec, tvec;
@@ -205,10 +222,10 @@ static Mat projectMarker(Ptr<aruco::Dictionary> &dictionary, int id, Mat cameraM
205
222
projectPoints (markerObjPoints, rvec, tvec, cameraMatrix, distCoeffs, corners);
206
223
207
224
vector< Point2f > originalCorners;
208
- originalCorners.push_back (Point2f (0 , 0 ));
209
- originalCorners.push_back (Point2f ((float )markerSizePixels, 0 ));
210
- originalCorners.push_back (Point2f ((float )markerSizePixels, (float )markerSizePixels));
211
- originalCorners.push_back (Point2f (0 , (float )markerSizePixels));
225
+ originalCorners.push_back (Point2f (0 + float (encloseMarker*markerSizePixels/ 4 ) , 0 + float (encloseMarker*markerSizePixels/ 4 ) ));
226
+ originalCorners.push_back (originalCorners[ 0 ]+ Point2f ((float )markerSizePixels, 0 ));
227
+ originalCorners.push_back (originalCorners[ 0 ]+ Point2f ((float )markerSizePixels, (float )markerSizePixels));
228
+ originalCorners.push_back (originalCorners[ 0 ]+ Point2f (0 , (float )markerSizePixels));
212
229
213
230
Mat transformation = getPerspectiveTransform (originalCorners, corners);
214
231
@@ -238,6 +255,11 @@ class CV_ArucoDetectionPerspective : public cvtest::BaseTest {
238
255
public:
239
256
CV_ArucoDetectionPerspective ();
240
257
258
+ enum checkWithParameter{
259
+ USE_APRILTAG=1 , // / Detect marker candidates :: using AprilTag
260
+ DETECT_INVERTED_MARKER, // / Check if there is a white marker
261
+ };
262
+
241
263
protected:
242
264
void run (int );
243
265
};
@@ -246,9 +268,10 @@ class CV_ArucoDetectionPerspective : public cvtest::BaseTest {
246
268
CV_ArucoDetectionPerspective::CV_ArucoDetectionPerspective () {}
247
269
248
270
249
- void CV_ArucoDetectionPerspective::run (int aprilDecimate ) {
271
+ void CV_ArucoDetectionPerspective::run (int tryWith ) {
250
272
251
273
int iter = 0 ;
274
+ int szEnclosed = 0 ;
252
275
Mat cameraMatrix = Mat::eye (3 , 3 , CV_64FC1);
253
276
Size imgSize (500 , 500 );
254
277
cameraMatrix.at < double >(0 , 0 ) = cameraMatrix.at < double >(1 , 1 ) = 650 ;
@@ -257,29 +280,35 @@ void CV_ArucoDetectionPerspective::run(int aprilDecimate) {
257
280
Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary (aruco::DICT_6X6_250);
258
281
259
282
// detect from different positions
260
- for (double distance = 0.1 ; distance <= 0.5 ; distance += 0.2 ) {
261
- for (int pitch = 0 ; pitch < 360 ; pitch += 60 ) {
262
- for (int yaw = 30 ; yaw <= 90 ; yaw += 50 ) {
283
+ for (double distance = 0.1 ; distance < 0.7 ; distance += 0.2 ) {
284
+ for (int pitch = 0 ; pitch < 360 ; pitch += (distance == 0.1 ? 60 : 180 ) ) {
285
+ for (int yaw = 70 ; yaw <= 120 ; yaw += 40 ) {
263
286
int currentId = iter % 250 ;
264
287
int markerBorder = iter % 2 + 1 ;
265
288
iter++;
266
289
vector< Point2f > groundTruthCorners;
267
- // create synthetic image
268
- Mat img =
269
- projectMarker (dictionary, currentId, cameraMatrix, deg2rad (yaw), deg2rad (pitch),
270
- distance, imgSize, markerBorder, groundTruthCorners);
271
290
272
- // detect markers
273
- vector< vector< Point2f > > corners;
274
- vector< int > ids;
275
291
Ptr<aruco::DetectorParameters> params = aruco::DetectorParameters::create ();
276
292
params->minDistanceToBorder = 1 ;
277
293
params->markerBorderBits = markerBorder;
278
294
279
- if (aprilDecimate == 1 ){
280
- params->cornerRefinementMethod = cv::aruco::CORNER_REFINE_APRILTAG;
295
+ // / create synthetic image
296
+ Mat img=
297
+ projectMarker (dictionary, currentId, cameraMatrix, deg2rad (yaw), deg2rad (pitch),
298
+ distance, imgSize, markerBorder, groundTruthCorners, szEnclosed);
299
+ // marker :: Inverted
300
+ if (CV_ArucoDetectionPerspective::DETECT_INVERTED_MARKER == tryWith){
301
+ img = ~img;
302
+ params->detectInvertedMarker = true ;
303
+ }
304
+
305
+ if (CV_ArucoDetectionPerspective::USE_APRILTAG == tryWith){
306
+ params->cornerRefinementMethod = cv::aruco::CORNER_REFINE_APRILTAG;
281
307
}
282
308
309
+ // detect markers
310
+ vector< vector< Point2f > > corners;
311
+ vector< int > ids;
283
312
aruco::detectMarkers (img, dictionary, corners, ids, params);
284
313
285
314
// check results
@@ -293,14 +322,33 @@ void CV_ArucoDetectionPerspective::run(int aprilDecimate) {
293
322
}
294
323
for (int c = 0 ; c < 4 ; c++) {
295
324
double dist = cv::norm (groundTruthCorners[c] - corners[0 ][c]); // TODO cvtest
296
- if (dist > 5 ) {
297
- ts->printf (cvtest::TS::LOG, " Incorrect marker corners position" );
298
- ts->set_failed_test_info (cvtest::TS::FAIL_BAD_ACCURACY);
299
- return ;
325
+ if (CV_ArucoDetectionPerspective::DETECT_INVERTED_MARKER == tryWith){
326
+ if (szEnclosed && dist > 3 ){
327
+ ts->printf (cvtest::TS::LOG, " Incorrect marker corners position" );
328
+ ts->set_failed_test_info (cvtest::TS::FAIL_BAD_ACCURACY);
329
+ return ;
330
+ }
331
+ if (!szEnclosed && dist >15 ){
332
+ ts->printf (cvtest::TS::LOG, " Incorrect marker corners position" );
333
+ ts->set_failed_test_info (cvtest::TS::FAIL_BAD_ACCURACY);
334
+ return ;
335
+ }
336
+ }
337
+ else {
338
+ if (dist > 5 ) {
339
+ ts->printf (cvtest::TS::LOG, " Incorrect marker corners position" );
340
+ ts->set_failed_test_info (cvtest::TS::FAIL_BAD_ACCURACY);
341
+ return ;
342
+ }
300
343
}
301
344
}
302
345
}
303
346
}
347
+ // change the state :: to detect an enclosed inverted marker
348
+ if ( CV_ArucoDetectionPerspective::DETECT_INVERTED_MARKER == tryWith && distance == 0.1 ){
349
+ distance -= 0.1 ;
350
+ szEnclosed++;
351
+ }
304
352
}
305
353
}
306
354
@@ -488,10 +536,16 @@ void CV_ArucoBitCorrection::run(int) {
488
536
}
489
537
490
538
typedef CV_ArucoDetectionPerspective CV_AprilTagDetectionPerspective;
539
+ typedef CV_ArucoDetectionPerspective CV_InvertedArucoDetectionPerspective;
540
+
541
+ TEST (CV_InvertedArucoDetectionPerspective, algorithmic) {
542
+ CV_InvertedArucoDetectionPerspective test;
543
+ test.safe_run (CV_ArucoDetectionPerspective::DETECT_INVERTED_MARKER);
544
+ }
491
545
492
546
TEST (CV_AprilTagDetectionPerspective, algorithmic) {
493
547
CV_AprilTagDetectionPerspective test;
494
- test.safe_run (1 );
548
+ test.safe_run (CV_ArucoDetectionPerspective::USE_APRILTAG );
495
549
}
496
550
497
551
TEST (CV_ArucoDetectionSimple, algorithmic) {
0 commit comments