-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Feature/aruco speedup (rebased with 4.x) #3151
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
Conversation
modules/aruco/src/aruco.cpp
Outdated
| vector< int > rotated(ncandidates, 0); | ||
| vector< uint8_t > validCandidates(ncandidates, 0); | ||
|
|
||
| const int min_perimeter = params->minSideLengthCanonicalImg * params->minSideLengthCanonicalImg; |
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.
"perimeter" is calculated by multiplying the sides of the square
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.
this was bug, fixed
modules/aruco/perf/perf_aruco.cpp
Outdated
|
|
||
| TEST(EstimateAruco, ArucoThird) | ||
| { | ||
| setNumThreads(1); |
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.
It's hack, is not it?
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.
Yes, this was done for debugging.
|
@AleksandrPanov : great work! Thanks a lot for finishing this PR. I just did not find the time. :/ |
90becbc to
42018ae
Compare
| // aruco3 detection is a bit worse from large distances it seems | ||
| if (run_with == checkWithParameter::USE_ARUCO3) { | ||
| max_dist = 0.2; | ||
| } |
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.
In fact, a too small perimeter marker is created (marker perimeter < 32 * 4). Need set minSideLengthCanonicalImg as 16 to avoid skip this marker.
5291225 to
3b3e47c
Compare
51bc0d3 to
3ac9bf6
Compare
| Mat image = _image.getMat(); | ||
| CV_Assert(image.total() != 0); | ||
|
|
||
| /// 1. CONVERT TO GRAY | ||
| Mat grey; | ||
| _convertToGrey(image, grey); |
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.
input image was gray already
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.
Add checks about assumptions of this code:
- not
.empty() CV_CheckType()
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.
these conditions were checked already (in detectMarkers)
added CV_DbgAssert:
CV_DbgAssert(grey.total() != 0);
CV_DbgAssert(grey.type() == CV_8UC1);
| Mat grey; | ||
| _convertToGrey(_image.getMat(), grey); |
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.
input image was gray already
|
|
||
| vector< vector< Point > > contours; | ||
|
|
||
| CV_Assert(_image.getMat().total() != 0); |
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.
this condition was checked already (in detectMarkers)
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.
assumption checks are necessary, see above
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.
added CV_DbgAssert:
CV_DbgAssert(grey.getMat().total() != 0);
CV_DbgAssert(grey.getMat().type() == CV_8UC1);
fixed
ed21325 to
ab550cd
Compare
| CV_Assert(_corners.size() == 4); | ||
| CV_Assert(_image.getMat().total() != 0); | ||
| CV_Assert(params->markerBorderBits > 0); |
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.
these conditions were checked already (in detectMarkers)
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.
It makes sense to keep them as CV_DbgAssert() anyway.
There are several static code analyzers which don't care about callers code but needs some checks.
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.
added CV_DbgAssert():
CV_DbgAssert(_corners.size() == 4);
CV_DbgAssert(_image.getMat().total() != 0);
CV_DbgAssert(params->markerBorderBits > 0);
modules/aruco/perf/perf_aruco.cpp
Outdated
| // detect markers | ||
| vector<vector<Point2f> > corners; | ||
| vector<int> ids; | ||
| TEST_CYCLE_N(10) |
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.
Why do you need fixed amount of iterations for performance test?
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.
was removed, insert just TEST_CYCLE()
| minOtsuStdDev: 5.0 | ||
| errorCorrectionRate: 0.6 | ||
|
|
||
| # new aruco functionality |
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.
# for aruco 3 should be better.
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.
fixed
modules/aruco/src/aruco.cpp
Outdated
| checkRead |= readParameter(fn["maxErroneousBitsInBorderRate"], params->maxErroneousBitsInBorderRate); | ||
| checkRead |= readParameter(fn["minOtsuStdDev"], params->minOtsuStdDev); | ||
| checkRead |= readParameter(fn["errorCorrectionRate"], params->errorCorrectionRate); | ||
| // new aruco functionality |
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.
aruco 3 parameters
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.
fixed
modules/aruco/perf/perf_aruco.cpp
Outdated
| int id = ids[i]; | ||
| const auto gold_corners = golds.find(id); | ||
| if (gold_corners != golds.end()) | ||
| for (int c = 0; c < 4; c++) |
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. Also it case of id is missing in golds the function returns 0 and test passes silently. I propose to return some very large value to highlight the issue.
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.
inserted distMap with std::numeric_limits<double>::max() default distance. Now getMaxDistance return max value of distMap. And if ids has no gold id, then getMaxDistance will return std::numeric_limits<double>::max().
ab550cd to
051b1f4
Compare
051b1f4 to
7e7e645
Compare
| checkRead |= readParameter(fn["errorCorrectionRate"], params->errorCorrectionRate); | ||
| // new aruco 3 functionality | ||
| checkRead |= readParameter(fn["useAruco3Detection"], params->useAruco3Detection); | ||
| checkRead |= readParameter(fn["minSideLengthCanonicalImg"], params->minSideLengthCanonicalImg); | ||
| checkRead |= readParameter(fn["minMarkerLengthRatioOriginalImg"], params->minMarkerLengthRatioOriginalImg); | ||
| return checkRead; |
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.
false result for old .xml files (from existed opencv versions) is an regression.
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.
There is no false result for old .xml files, because |= operator is using.
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.
Also, test can_find_diamondmarkers with read old .xml files was added in prev PR. This test successfully completed.
Only &= operator could add false result for old .xml files.
| CV_Assert(_corners.size() == 4); | ||
| CV_Assert(_image.getMat().total() != 0); | ||
| CV_Assert(params->markerBorderBits > 0); |
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.
It makes sense to keep them as CV_DbgAssert() anyway.
There are several static code analyzers which don't care about callers code but needs some checks.
| size_t optLevel = 0; | ||
| float dist = std::numeric_limits<float>::max(); | ||
| for (size_t i = 0; i < img_pyr.size(); ++i) { | ||
| const float scale = img_pyr[i].cols / static_cast<float>(scaled_width); |
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.
scaled_width > 0 check is necessary.
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.
scaled_width checked after resize image.
added CV_Assert(scaled_width > 0);
| Mat image = _image.getMat(); | ||
| CV_Assert(image.total() != 0); | ||
|
|
||
| /// 1. CONVERT TO GRAY | ||
| Mat grey; | ||
| _convertToGrey(image, grey); |
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.
Add checks about assumptions of this code:
- not
.empty() CV_CheckType()
7e7e645 to
a0e036a
Compare
|
@alalek thx for review, I fixed your remarks |
|
|
||
|
|
||
| void CV_ArucoBoardPose::run(int) { | ||
| void CV_ArucoBoardPose::run(int run_with) { |
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.
Wrong usage. Don't change semantic of parameters.
Check the base class:
// the main procedure of the test
virtual void run( int start_from );
Use derived class or template.
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.
removed run_with and add ArucoAlgParams to test classes constructor. Also field Ptr<aruco::DetectorParameters> params was added to test classes.
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.
fixed
289a3bc to
ad9c69c
Compare
|
@alalek thx, issues were fixed. Is there anything else to fix? |
|
|
||
| TEST(CV_Aruco3DetectionPerspective, algorithmic) { | ||
| CV_Aruco3DetectionPerspective test; | ||
| test.safe_run(CV_ArucoDetectionPerspective::USE_ARUCO3); |
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.
The issue with parameter misusing with this test too.
https://github.com/opencv/opencv/blob/4.5.5/modules/ts/include/opencv2/ts.hpp#L407-L411
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.
@alalek, fixed:
parameter tryWith was removed, parameter ArucoAlgParams was added as field of class CV_ArucoDetectionPerspective
ad9c69c to
8e22f6d
Compare
|
@alalek thx a lot) issue with |
|
@AleksandrPanov I have some questions regarding the changes in this PR. I'm currently using the Aruco detection algorithm in an older version of OpenCV. I've heard from other sources that the opencv implementation was outdated because of the GPL licensing issues #2242. But @asmorkalov recently commented that a new independent implementation was brought into OpenCV with this PR. From my limited experience here, it seems like the primary improvement here was improving the processing speed (I also briefly skimmed the attached paper), but speed is not a huge concern for my use case at the moment. I'm curious about the following things however.
|
Added improvements to the ArUco module made by the author @urbste. New PR was created to fix issues and rebase with 4.x (and to avoid regression in original PR).
This PR:
ArucoDetectorclass (like QRCodeDetector class). I suggest return global threshold parameters in next PR after createArucoDetectorclass and API changes (this changes could significantly increase "git diff").Configuration - Ryzen 7 2700x, 32GB 2933 mhz DDR4
Performance tests result (image size is 1440x1440 - the number of pixels is the same as in FHD image with size 1920x1080):
Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.