-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added detection of inverted Markers, tests included #2055
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -182,12 +182,29 @@ static void getSyntheticRT(double yaw, double pitch, double distance, Mat &rvec, | |
*/ | ||
static Mat projectMarker(Ptr<aruco::Dictionary> &dictionary, int id, Mat cameraMatrix, double yaw, | ||
double pitch, double distance, Size imageSize, int markerBorder, | ||
vector< Point2f > &corners) { | ||
vector< Point2f > &corners, int encloseMarker=0) { | ||
|
||
// canonical image | ||
Mat markerImg; | ||
Mat marker, markerImg; | ||
const int markerSizePixels = 100; | ||
aruco::drawMarker(dictionary, id, markerSizePixels, markerImg, markerBorder); | ||
|
||
aruco::drawMarker(dictionary, id, markerSizePixels, marker, markerBorder); | ||
marker.copyTo(markerImg); | ||
|
||
if(encloseMarker){ //to enclose the marker | ||
int enclose = int(marker.rows/4); | ||
markerImg = Mat::zeros(marker.rows+(2*enclose), marker.cols+(enclose*2), CV_8UC1); | ||
|
||
Mat field= markerImg.rowRange(int(enclose), int(markerImg.rows-enclose)) | ||
.colRange(int(0), int(markerImg.cols)); | ||
field.setTo(255); | ||
field= markerImg.rowRange(int(0), int(markerImg.rows)) | ||
.colRange(int(enclose), int(markerImg.cols-enclose)); | ||
field.setTo(255); | ||
|
||
field = markerImg(Rect(enclose,enclose,marker.rows,marker.cols)); | ||
marker.copyTo(field); | ||
} | ||
|
||
// get rvec and tvec for the perspective | ||
Mat rvec, tvec; | ||
|
@@ -205,10 +222,10 @@ static Mat projectMarker(Ptr<aruco::Dictionary> &dictionary, int id, Mat cameraM | |
projectPoints(markerObjPoints, rvec, tvec, cameraMatrix, distCoeffs, corners); | ||
|
||
vector< Point2f > originalCorners; | ||
originalCorners.push_back(Point2f(0, 0)); | ||
originalCorners.push_back(Point2f((float)markerSizePixels, 0)); | ||
originalCorners.push_back(Point2f((float)markerSizePixels, (float)markerSizePixels)); | ||
originalCorners.push_back(Point2f(0, (float)markerSizePixels)); | ||
originalCorners.push_back(Point2f(0+float(encloseMarker*markerSizePixels/4), 0+float(encloseMarker*markerSizePixels/4))); | ||
originalCorners.push_back(originalCorners[0]+Point2f((float)markerSizePixels, 0)); | ||
originalCorners.push_back(originalCorners[0]+Point2f((float)markerSizePixels, (float)markerSizePixels)); | ||
originalCorners.push_back(originalCorners[0]+Point2f(0, (float)markerSizePixels)); | ||
|
||
Mat transformation = getPerspectiveTransform(originalCorners, corners); | ||
|
||
|
@@ -238,6 +255,11 @@ class CV_ArucoDetectionPerspective : public cvtest::BaseTest { | |
public: | ||
CV_ArucoDetectionPerspective(); | ||
|
||
enum checkWithParameter{ | ||
USE_APRILTAG=1, /// Detect marker candidates :: using AprilTag | ||
DETECT_INVERTED_MARKER, /// Check if there is a white marker | ||
}; | ||
|
||
protected: | ||
void run(int); | ||
}; | ||
|
@@ -246,9 +268,10 @@ class CV_ArucoDetectionPerspective : public cvtest::BaseTest { | |
CV_ArucoDetectionPerspective::CV_ArucoDetectionPerspective() {} | ||
|
||
|
||
void CV_ArucoDetectionPerspective::run(int aprilDecimate) { | ||
void CV_ArucoDetectionPerspective::run(int tryWith) { | ||
|
||
int iter = 0; | ||
int szEnclosed = 0; | ||
Mat cameraMatrix = Mat::eye(3, 3, CV_64FC1); | ||
Size imgSize(500, 500); | ||
cameraMatrix.at< double >(0, 0) = cameraMatrix.at< double >(1, 1) = 650; | ||
|
@@ -257,29 +280,35 @@ void CV_ArucoDetectionPerspective::run(int aprilDecimate) { | |
Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250); | ||
|
||
// detect from different positions | ||
for(double distance = 0.1; distance <= 0.5; distance += 0.2) { | ||
for(int pitch = 0; pitch < 360; pitch += 60) { | ||
for(int yaw = 30; yaw <= 90; yaw += 50) { | ||
for(double distance = 0.1; distance < 0.7; distance += 0.2) { | ||
for(int pitch = 0; pitch < 360; pitch += (distance == 0.1? 60:180)) { | ||
for(int yaw = 70; yaw <= 120; yaw += 40){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
yaw: 70, 110 ? Old yaw values are: 30, 80 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. even though the detection of a default marker happens using that yaw value, it was not the case for the inverted marker, however, it also occurs in the opposite way, that is, where the inverted marker is detected more easily than the default marker. |
||
int currentId = iter % 250; | ||
int markerBorder = iter % 2 + 1; | ||
iter++; | ||
vector< Point2f > groundTruthCorners; | ||
// create synthetic image | ||
Mat img = | ||
projectMarker(dictionary, currentId, cameraMatrix, deg2rad(yaw), deg2rad(pitch), | ||
distance, imgSize, markerBorder, groundTruthCorners); | ||
|
||
// detect markers | ||
vector< vector< Point2f > > corners; | ||
vector< int > ids; | ||
Ptr<aruco::DetectorParameters> params = aruco::DetectorParameters::create(); | ||
params->minDistanceToBorder = 1; | ||
params->markerBorderBits = markerBorder; | ||
|
||
if(aprilDecimate == 1){ | ||
params->cornerRefinementMethod = cv::aruco::CORNER_REFINE_APRILTAG; | ||
/// create synthetic image | ||
Mat img= | ||
projectMarker(dictionary, currentId, cameraMatrix, deg2rad(yaw), deg2rad(pitch), | ||
distance, imgSize, markerBorder, groundTruthCorners, szEnclosed); | ||
szk1509 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// marker :: Inverted | ||
if(CV_ArucoDetectionPerspective::DETECT_INVERTED_MARKER == tryWith){ | ||
img = ~img; | ||
params->detectInvertedMarker = true; | ||
} | ||
|
||
if(CV_ArucoDetectionPerspective::USE_APRILTAG == tryWith){ | ||
params->cornerRefinementMethod = cv::aruco::CORNER_REFINE_APRILTAG; | ||
} | ||
|
||
// detect markers | ||
vector< vector< Point2f > > corners; | ||
vector< int > ids; | ||
aruco::detectMarkers(img, dictionary, corners, ids, params); | ||
|
||
// check results | ||
|
@@ -293,14 +322,33 @@ void CV_ArucoDetectionPerspective::run(int aprilDecimate) { | |
} | ||
for(int c = 0; c < 4; c++) { | ||
double dist = cv::norm(groundTruthCorners[c] - corners[0][c]); // TODO cvtest | ||
if(dist > 5) { | ||
ts->printf(cvtest::TS::LOG, "Incorrect marker corners position"); | ||
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); | ||
return; | ||
if(CV_ArucoDetectionPerspective::DETECT_INVERTED_MARKER == tryWith){ | ||
if(szEnclosed && dist > 3){ | ||
ts->printf(cvtest::TS::LOG, "Incorrect marker corners position"); | ||
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); | ||
return; | ||
} | ||
if(!szEnclosed && dist >15){ | ||
ts->printf(cvtest::TS::LOG, "Incorrect marker corners position"); | ||
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); | ||
return; | ||
} | ||
} | ||
else{ | ||
if(dist > 5) { | ||
ts->printf(cvtest::TS::LOG, "Incorrect marker corners position"); | ||
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); | ||
return; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
// change the state :: to detect an enclosed inverted marker | ||
if( CV_ArucoDetectionPerspective::DETECT_INVERTED_MARKER == tryWith && distance == 0.1 ){ | ||
distance -= 0.1; | ||
szEnclosed++; | ||
} | ||
} | ||
} | ||
|
||
|
@@ -488,10 +536,16 @@ void CV_ArucoBitCorrection::run(int) { | |
} | ||
|
||
typedef CV_ArucoDetectionPerspective CV_AprilTagDetectionPerspective; | ||
typedef CV_ArucoDetectionPerspective CV_InvertedArucoDetectionPerspective; | ||
|
||
TEST(CV_InvertedArucoDetectionPerspective, algorithmic) { | ||
CV_InvertedArucoDetectionPerspective test; | ||
test.safe_run(CV_ArucoDetectionPerspective::DETECT_INVERTED_MARKER); | ||
} | ||
|
||
TEST(CV_AprilTagDetectionPerspective, algorithmic) { | ||
CV_AprilTagDetectionPerspective test; | ||
test.safe_run(1); | ||
test.safe_run(CV_ArucoDetectionPerspective::USE_APRILTAG); | ||
} | ||
|
||
TEST(CV_ArucoDetectionSimple, algorithmic) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix indentation (it is "jumping").