Skip to content
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

Speed up ChessBoardDetector::findQuadNeighbors #24605

Conversation

MaximSmolskiy
Copy link
Contributor

@MaximSmolskiy MaximSmolskiy commented Nov 28, 2023

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_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

  • I agree to contribute to the project under Apache 2 License.
  • 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
  • The PR is proposed to the proper branch
  • 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

@AleksandrPanov
Copy link
Contributor

AleksandrPanov commented Nov 29, 2023

@MaximSmolskiy, thanks for your contribution, looks great!

I need some time to check result in OpenCV synthetic benchmark and checkKDTree logic.

Copy link
Contributor

@AleksandrPanov AleksandrPanov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR was tested with OpenCV synthetic benchmark.

Images such as this were used:
_perspective_undistorted_gaussNoise_35

There is no accuracy regressions.

image

Performance improved from 106 seconds to 67 seconds (~37%).

👍

Comment on lines +1633 to +1635
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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MaximSmolskiy, is there a case for which it will be necessary to increase the search radius? Is this possible only with large distortion?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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)

@asmorkalov
Copy link
Contributor

@vpisarev Could you take a look please.

@asmorkalov asmorkalov merged commit b1b59c8 into opencv:4.x Dec 11, 2023
26 checks passed
@MaximSmolskiy MaximSmolskiy deleted the speed-up-ChessBoardDetector-findQuadNeighbors branch December 11, 2023 16:15
@asmorkalov asmorkalov mentioned this pull request Jan 19, 2024
thewoz pushed a commit to thewoz/opencv that referenced this pull request May 29, 2024
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants