Skip to content

Improve QR code version estimation#22695

Merged
asmorkalov merged 1 commit intoopencv:4.xfrom
AleksandrPanov:qr_improve_version_detect
Nov 28, 2022
Merged

Improve QR code version estimation#22695
asmorkalov merged 1 commit intoopencv:4.xfrom
AleksandrPanov:qr_improve_version_detect

Conversation

@AleksandrPanov
Copy link
Copy Markdown
Contributor

@AleksandrPanov AleksandrPanov commented Oct 26, 2022

QR codes with version 7 or greater store a special 18 bit code with the version number of the code:

https://www.thonky.com/qr-code-tutorial/format-version-information
https://www.thonky.com/qr-code-tutorial/format-version-tables

This PR reads this QR information to determine the version.

Also, to determine the version of QR codes < 7, added method with getNumModules() function.
To check the correctness, a benchmark was launched:

  • correctly found 10 versions in category high_version instead of 2
  • +6% monitor decode, +0.5% total correct decoded images, no regression

Logging from benchmark:
new_version.txt
base.txt

Pull Request Readiness Checklist

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

@asmorkalov asmorkalov changed the title qr improve version detect Improve QR code version estimation Nov 17, 2022
@asmorkalov asmorkalov added this to the 4.7.0 milestone Nov 17, 2022
@AleksandrPanov AleksandrPanov force-pushed the qr_improve_version_detect branch from 3240ebc to 53964a3 Compare November 17, 2022 14:32
@asmorkalov asmorkalov self-requested a review November 17, 2022 16:04
@AleksandrPanov AleksandrPanov force-pushed the qr_improve_version_detect branch 4 times, most recently from 82a247a to 0a8c040 Compare November 18, 2022 02:39
@AleksandrPanov AleksandrPanov marked this pull request as ready for review November 18, 2022 08:59
@AleksandrPanov AleksandrPanov force-pushed the qr_improve_version_detect branch from 0a8c040 to 8566b76 Compare November 18, 2022 09:05
@AleksandrPanov AleksandrPanov force-pushed the qr_improve_version_detect branch from 8550665 to ea53a7b Compare November 23, 2022 17:04
@AleksandrPanov AleksandrPanov marked this pull request as draft November 23, 2022 21:42
@AleksandrPanov AleksandrPanov force-pushed the qr_improve_version_detect branch 2 times, most recently from a6d055e to 091f3e6 Compare November 24, 2022 02:12
@AleksandrPanov AleksandrPanov marked this pull request as ready for review November 24, 2022 02:12
@asmorkalov asmorkalov self-assigned this Nov 24, 2022
@AleksandrPanov AleksandrPanov force-pushed the qr_improve_version_detect branch 4 times, most recently from 2ea256c to 79c63c6 Compare November 25, 2022 10:50
@AleksandrPanov
Copy link
Copy Markdown
Contributor Author

@asmorkalov

@AleksandrPanov AleksandrPanov force-pushed the qr_improve_version_detect branch from 79c63c6 to 4b41946 Compare November 25, 2022 13:36
@asmorkalov asmorkalov self-requested a review November 28, 2022 14:01
Copy link
Copy Markdown
Contributor

@asmorkalov asmorkalov left a comment

Choose a reason for hiding this comment

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

👍

@AleksandrPanov AleksandrPanov force-pushed the qr_improve_version_detect branch from 3d0a706 to ed3810f Compare November 28, 2022 14:46
@asmorkalov asmorkalov merged commit eb68de9 into opencv:4.x Nov 28, 2022
Copy link
Copy Markdown
Member

@rogday rogday left a comment

Choose a reason for hiding this comment

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

Thank you for contribution!
Just comments, feel free to ignore.
EDIT: welp, I'm late

* findPatternsVerticesPoints() may be erroneous, so they are checked.
*/
static inline std::pair<int, int> matchPatternPoints(const vector<Point> &finderPattern,
const vector<Point2f> cornerPointsQR) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks like it should be a reference

sqrt(normL2Sqr<float>(cornerPointsQR[0] - cornerPointsQR[3]))*0.5f;
const float maxRelativeDistance = .1f;

if (distanceToOrig/originalQrSide > maxRelativeDistance)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not sure, looks suspicious: squared distance is divided by mean of distances

vector<vector<Point>> finderPatterns;
double numModulesX = 0., numModulesY = 0.;
bool flag = findPatternsVerticesPoints(finderPatterns);
if (flag) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: negate the condition to reduce nesting.

double numModulesX = 0., numModulesY = 0.;
bool flag = findPatternsVerticesPoints(finderPatterns);
if (flag) {
vector<double> pattern_distance(4);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why is this a vector?

if (flag) {
vector<double> pattern_distance(4);
for (auto& pattern : finderPatterns) {
auto indexes = matchPatternPoints(pattern, original_points);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: name both elements of the pair so that's easier to read.

Comment on lines +2527 to +2528
if (roundingError < thresholdFinderPattern)
useFinderPattern = true;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

useFinderPattern = (roundingError < thresholdFinderPattern);

bool useCode = false;
int versionByCode = 7;
if (cvRound(versionByFinderPattern) >= 7 || versionByTransition >= 7) {
vector<std::pair<double, int>> versionAndDistances;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why do we need this? Should be pair bestVersion instead, then push_back -> bestVersion = std::min(bestVersion, ...);

version_size = 21 + (version - 1) * 4;
CV_LOG_INFO(NULL, "QR corners: " << original_points[0] << " " << original_points[1] << " " << original_points[2] <<
" " << original_points[3]);
if ( !(0 < version && version <= 40) ) { return false; }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: if ( version <= 0 || version > 40) { return false; } looks far more readable

Comment on lines +2269 to +2271
if (1.f - minSide / maxSide > patternMaxRelativeLen)
return false;
return true;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

return (1.f - minSide / maxSide <= patternMaxRelativeLen);

@alalek alalek mentioned this pull request Jan 8, 2023
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.

4 participants