CARVIEW |
Navigation Menu
-
-
Notifications
You must be signed in to change notification settings - Fork 56.2k
Detection and decoding of curved QR-codes #18003
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
Co-authored-by: Nesterov Alexander <nesoldr@gmail.com>
bb90559
to
79a37c5
Compare
89e1815
to
f67ef55
Compare
f67ef55
to
a243657
Compare
} | ||
num_points_at_side += it->second.size(); | ||
} | ||
mean_step /= num_points_at_side; |
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 add test for check zero divided
modules/objdetect/src/qrcode.cpp
Outdated
int count = -1; | ||
for(size_t j = 0; j < it->second.size() - 1; j++) | ||
{ | ||
count++; |
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 replace near with j++
modules/objdetect/src/qrcode.cpp
Outdated
for (it=complete_curved_sides.begin(); it!=complete_curved_sides.end(); ++it) | ||
{ | ||
int count = -1; | ||
for(size_t j = 0; j < it->second.size() - 1; j++) |
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 replace all constants outside cycles because cycle call size()
function every iteration
modules/objdetect/src/qrcode.cpp
Outdated
return true; | ||
} | ||
|
||
vector<vector<float> > QRDecode::computeSpline(vector<int> &x_arr, vector<int> &y_arr) |
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.
vector<vector<float> > QRDecode::computeSpline(vector<int> &x_arr, vector<int> &y_arr) | |
vector<vector<float> > QRDecode::computeSpline(const vector<int> &x_arr, const vector<int> &y_arr) |
modules/objdetect/src/qrcode.cpp
Outdated
|
||
vector<vector<float> > QRDecode::computeSpline(vector<int> &x_arr, vector<int> &y_arr) | ||
{ | ||
int n = (int)y_arr.size(); |
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.
int n = (int)y_arr.size(); | |
const int n = (int)y_arr.size(); |
modules/objdetect/src/qrcode.cpp
Outdated
{ | ||
if ((x > x_arr[i]) && (x <= x_arr[i + 1])) | ||
{ | ||
float y = S[i][0] + S[i][1] * (x - x_arr[i]) + S[i][2] * pow((x - x_arr[i]), 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.
please use multiplication instead pow
modules/objdetect/src/qrcode.cpp
Outdated
x_arr.push_back(cvRound(spline_points[j].x)); | ||
y_arr.push_back(cvRound(spline_points[j].y)); | ||
} | ||
if (abs(x_arr.front() - x_arr.back()) > abs(y_arr.front() - y_arr.back())) |
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 use swap between x
and y
for calculate only one condition branch
|
||
bool QRDecode::divideIntoEvenSegments(vector<vector<Point2f> > &segments_points) | ||
{ | ||
vector<vector<Point2f> > spline_lines(NUM_SIDES); |
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 add NUM_SIDES
into class
modules/objdetect/src/qrcode.cpp
Outdated
mean_num_points_in_line += spline_lines[i].size(); | ||
} | ||
mean_num_points_in_line /= NUM_SIDES; | ||
int min_num_points = 1, max_num_points = cvRound(mean_num_points_in_line / 2.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.
int min_num_points = 1, max_num_points = cvRound(mean_num_points_in_line / 2.0); | |
const int min_num_points = 1, max_num_points = cvRound(mean_num_points_in_line / 2.0); |
modules/objdetect/src/qrcode.cpp
Outdated
mean_of_two_sides += mean_dist_in_segment; | ||
} | ||
mean_of_two_sides /= NUM_SIDES; | ||
if (mean_of_two_sides < 0.5) |
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 name magic number
modules/objdetect/src/qrcode.cpp
Outdated
if (abs(temp_point_start.x - temp_point_end.x) > | ||
abs(temp_point_start.y - temp_point_end.y)) | ||
{ | ||
if(segments_points[i].front().y > segments_points[(i+1)%2].front().y) | ||
{ | ||
current_curved_side = segments_points[i]; | ||
opposite_curved_side = segments_points[(i+1)%2]; | ||
} | ||
} | ||
else | ||
{ | ||
if(segments_points[i].front().x < segments_points[(i+1)%2].front().x) | ||
{ | ||
current_curved_side = segments_points[i]; | ||
opposite_curved_side = segments_points[(i+1)%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.
please revise conditions (maybe you can do it simpler)
modules/objdetect/src/qrcode.cpp
Outdated
if (complete_curved_sides.size() < 2) | ||
{ | ||
for (size_t i = 0; i < NUM_SIDES; i++) | ||
{ | ||
if(complete_curved_sides.count(curved_indexes[i]) == 0) | ||
{ | ||
int idx_second_cur_side = curved_indexes[i]; | ||
complete_curved_sides.insert(std::pair<int,vector<Point> >(idx_second_cur_side, sides_points[idx_second_cur_side])); | ||
} | ||
} | ||
} | ||
std::map<int,vector<Point> >::iterator it; | ||
for (it = complete_curved_sides.begin(); it != complete_curved_sides.end(); ++it) | ||
{ | ||
Point p1 = it->second.front(); | ||
Point p2 = it->second.back(); | ||
if (abs(p1.x - p2.x) > abs(p1.y - p2.y)) | ||
{ | ||
sort(it->second.begin(), it->second.end(), sortPointsByX()); | ||
} | ||
else | ||
{ | ||
sort(it->second.begin(), it->second.end(), sortPointsByY()); | ||
} | ||
} |
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 add it into new method
modules/objdetect/src/qrcode.cpp
Outdated
CV_TRACE_FUNCTION(); | ||
const double multiplyingFactor = (version < 3) ? 1 : | ||
(version == 3) ? 1.5 : | ||
version * (5 + version - 4); |
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.
version * (5 + version - 4); | |
version * (version + 1); |
872654c
to
5d3f886
Compare
5d3f886
to
7380ea4
Compare
modules/objdetect/src/qrcode.cpp
Outdated
((a1.x * a2.y - a1.y * a2.x) * (b1.x - b2.x) - | ||
(b1.x * b2.y - b1.y * b2.x) * (a1.x - a2.x)) / | ||
((a1.x - a2.x) * (b1.y - b2.y) - | ||
(a1.y - a2.y) * (b1.x - b2.x)), |
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.
divisor should be pre-calculated and checked for 0 (eps tolerance) or NaNs.
Or ensure that caller works well with Inf/NaN values and filter them out later.
modules/objdetect/src/qrcode.cpp
Outdated
if (sqrt(A*A + B*B) == 0) return 0; | ||
result = abs((A * a.x - B * a.y + C)) / sqrt(A*A + B*B); |
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.
Avoid calculation of sqrt()
expression twice.
modules/objdetect/src/qrcode.cpp
Outdated
} | ||
num_points_at_side += num_points_at_pattern; | ||
} | ||
if (num_points_at_side == 0) { return false; } |
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 use separate line for if
body, even for simple cases.
It is important to see the real code coverage.
a06167d
to
064142a
Compare
064142a
to
8d05d93
Compare
Hi! Last year, I defended my PhD in Engineering and Applied Science, regarding a thesis which involved huge use of QR Codes, at the time we didn't realize OpenCV had included a curved QR Code decoder, it is amazing the work the community has been done in recent years. In the thesis, we tackled the recovery of QR Codes from curved surfaces using Thin Plate Splines (Chapter 3 of https://diposit.ub.edu/dspace/bitstream/2445/185845/1/IBA_PhD_THESIS.pdf). Is there any paper regarding the implementation here presented of the use of splines to extract the QR Code? If we understand correctly, the above presented method uses the splines to fit the outer contour of the QR Code? We would like to be able to compare our method and the one presented here, and if able to present the research of the comparison and later attempt to make a pull request. TL;DR: Looking for a paper related with this method. |
These changes add detection and decoding of curved QR-codes