java-topology/defects/opencv/patch/opencv-0001-qrdecode-divideintoevensegments-spline-find.patch

56 lines
2.8 KiB
Diff

# UNDF: UNDF-2026-000000485
--- a/modules/objdetect/src/qrcode.cpp
+++ b/modules/objdetect/src/qrcode.cpp
@@ -2088,12 +2088,17 @@ bool QRDecode::divideIntoEvenSegments(vector<vector<Point2f> > &segments_points)
float mean_num_points_in_line = 0.0;
for (int i = 0; i < NUM_SIDES; i++)
{
mean_num_points_in_line += spline_lines[i].size();
}
mean_num_points_in_line /= NUM_SIDES;
const int min_num_points = 1, max_num_points = cvRound(mean_num_points_in_line / 2.0);
float linear_threshold = 0.5f;
for (int num = min_num_points; num < max_num_points; num++)
{
- for (int i = 0; i < NUM_SIDES; i++)
+ // Track spline indices directly alongside points so that the
+ // measurement loop below can use iterator arithmetic instead of
+ // calling std::find(spline_lines[i]...) for every segment boundary.
+ // Without this, each call is O(S) and the outer num-loop makes the
+ // full function O(max_num_points * num * S) ≈ O(S²) per side.
+ vector<vector<int> > seg_indices(NUM_SIDES);
+ for (int i = 0; i < NUM_SIDES; i++)
{
segments_points[i].clear();
+ seg_indices[i].clear();
int size = (int)spline_lines[i].size();
float step = static_cast<float>(size) / num;
for (int j = 0; j < num; j++)
{
float val = j * step;
int idx = cvRound(val) >= size ? size - 1 : cvRound(val);
segments_points[i].push_back(spline_lines[i][idx]);
+ seg_indices[i].push_back(idx);
}
segments_points[i].push_back(spline_lines[i].back());
+ seg_indices[i].push_back((int)spline_lines[i].size() - 1);
}
float mean_of_two_sides = 0.0;
for (int i = 0; i < NUM_SIDES; i++)
{
float mean_dist_in_segment = 0.0;
for (size_t j = 0; j < segments_points[i].size() - 1; j++)
{
Point2f segment_start = segments_points[i][j];
Point2f segment_end = segments_points[i][j + 1];
- vector<Point2f>::iterator it_start, it_end, it;
- it_start = std::find(spline_lines[i].begin(), spline_lines[i].end(), segment_start);
- it_end = std::find(spline_lines[i].begin(), spline_lines[i].end(), segment_end);
+ // Use pre-recorded indices: O(1) instead of O(S) std::find.
+ vector<Point2f>::iterator it_start = spline_lines[i].begin() + seg_indices[i][j];
+ vector<Point2f>::iterator it_end = spline_lines[i].begin() + seg_indices[i][j + 1];
+ vector<Point2f>::iterator it;
float max_dist_to_line = 0.0;
for (it = it_start; it != it_end; it++)
{