Properly handle empty centers in findCirclesGrid#19498
Conversation
|
@mattalvarado Thanks for the contribution! The same code exists in branch 3.4 and it looks like the same bug exists there too. Please re-base the patch to 3.4 and re-target it to 3.4 branch. 3.4 is merged to master weekly or biweekly and will be applied to master too. Also it'll some test is required to proof the solution. |
modules/calib3d/src/calibinit.cpp
Outdated
| } | ||
|
|
||
| if (!H.empty()) // undone rectification | ||
| if (isValid && !H.empty()) // undone rectification |
There was a problem hiding this comment.
relates #19079
The problem is that original code returns transformed (rectified) corners for the "false" result too.
Why do we need to return these rectified corners on detection failure?
Please provide more details about observed issue. What error message did you get?
BTW, you can see this corners problem by launching calib3d test with and without your patch:
./bin/opencv_test_calib3d --gtest_filter=*regression_18713* --test_debug=10
There was a problem hiding this comment.
Hi @alalek, Yep #19079 introduced the issue.
Since the rectification code was removed from the isFound conditional in the main attempts for loop, we need to add back in that check before attempting to rectify the centers.
The error occurs when the attempts loop reaches its last attempt. If no centers are found on the last attempt, but centers were found on one of the previous attempts, H will be valid but centers will be empty. The final !H.empty() conditional will then attempt to transform a empty container of centers which will trigger the following assertion:
opencv/modules/core/src/matmul.dispatch.cpp:439: error: (-215:Assertion failed) scn == m.cols || scn + 1 == m.cols in function 'transform'
I attempted to preserve the original function interface, and figured checking if the result was valid before rectifying the centers was the best way to do that.
There was a problem hiding this comment.
Perhaps I got this. Probably we should check for corners.empty() instead.
Please capture points values (std::cout << Mat(points) << std::endl) which cause this error, so we can add regression test for that.
(add patternSize / flags arguments values too)
There was a problem hiding this comment.
I figured isValid was equivalent to !centers.empty(), but I am happy to change this to check the centers directly. I attached the image which failed for reference. I believe the partial circle grid is what throws the logic off.
I am new to the unit testing framework for OpenCV. What is the best way to add the test for detectors like this? Should I hardcode the image contents in the test?
The patternSize is used was 13x8 and I used the default args for flags and blobDetector. Those are CALIB_CB_SYMMETRIC_GRID and SimpleBlobDetector::create() respectively
There was a problem hiding this comment.
I just took a look at the regression_18713 test. I port this issue to a similar test
@asmorkalov Happy to help. Which 3.4 branch should I rebase this onto? |
|
3.4 is branch name, not particular version. |
|
This patch should go into 3.4 branch first. Please:
Note: no needs to re-open PR, apply changes "inplace". |
a4eb71e to
1c98b25
Compare
|
@alalek @asmorkalov Apologies for the confusion on 3.4. I was accidentally looking at tags and not branches. I added a test for this regression, and should have rebased this onto 3.4. Please let me know if I need to make any other changes. |
alalek
left a comment
There was a problem hiding this comment.
Well done! Thank you for contribution 👍
Happy to help! Thanks for your patience. |

A recent refactor of
findCirclesGridintroduced a bug which does not properly handle the case when no centers are detected. This resolves that issue by explicitly checking if the centers result is valid before attempting to transform them.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.