Speed up ChessBoardDetector::findQuadNeighbors#24605
Conversation
|
@MaximSmolskiy, thanks for your contribution, looks great! I need some time to check result in OpenCV synthetic benchmark and check |
There was a problem hiding this comment.
PR was tested with OpenCV synthetic benchmark.
Images such as this were used:

There is no accuracy regressions.
Performance improved from 106 seconds to 67 seconds (~37%).
👍
| float radius = cur_quad.edge_len * thresh_scale + 1; | ||
| const cvflann::SearchParams search_params(-1); | ||
| int neighbors_count = all_quads_pts_index.radiusSearch(query, neighbors_indices, neighbors_dists, radius, search_params); |
There was a problem hiding this comment.
@MaximSmolskiy, is there a case for which it will be necessary to increase the search radius? Is this possible only with large distortion?
There was a problem hiding this comment.
@AleksandrPanov All these changes shouldn't change original behavior. I took this radius because below we have
if (dist < min_dist &&
dist <= cur_quad.edge_len*thresh_scale &&
dist <= q_k.edge_len*thresh_scale )
which means that we accept distance only if it less than cur_quad.edge_len * thresh_scale.
So, there is no sense in searching neighbors with radius greater than cur_quad.edge_len * thresh_scale - because we will never accept them further.
And I added + 1 as something like quite big "epsilon" to prevent possible problems with corner cases (e.g., if we want to search neighbors with radius <= R1 and flann module expects that if we pass radius R2 to it, then it searchs neighbors with condition radius < R2, then we should pass as R2 not exactly R1, but R1 + eps, where eps > 0 - this is just theoretical example, I don't know exactly in what area flann module searchs neighbors - radius < R2 or radius <= R2)
|
@vpisarev Could you take a look please. |
…dDetector-findQuadNeighbors Speed up ChessBoardDetector::findQuadNeighbors opencv#24605 ### Pull Request Readiness Checklist Replaced brute-force algorithm with O(N^2) time complexity with kd-tree with something like O(N * log N) time complexity (maybe only in average case). For example, on image from opencv#23558 without quads filtering (by using `CALIB_CB_FILTER_QUADS` flag) finding chessboards corners took ~770 seconds on my laptop, of which finding quads neighbors took ~620 seconds. Now finding chessboards corners takes ~155-160 seconds, of which finding quads neighbors takes only ~5-10 seconds. See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake

Pull Request Readiness Checklist
Replaced brute-force algorithm with O(N^2) time complexity with kd-tree with something like O(N * log N) time complexity (maybe only in average case).
For example, on image from #23558 without quads filtering (by using
CALIB_CB_FILTER_QUADSflag) finding chessboards corners took ~770 seconds on my laptop, of which finding quads neighbors took ~620 seconds.Now finding chessboards corners takes ~155-160 seconds, of which finding quads neighbors takes only ~5-10 seconds.
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.