Skip to content

Optimize camera matrix undistortion#27001

Merged
asmorkalov merged 2 commits intoopencv:4.xfrom
DanBmh:opt_newoptcm
Mar 11, 2025
Merged

Optimize camera matrix undistortion#27001
asmorkalov merged 2 commits intoopencv:4.xfrom
DanBmh:opt_newoptcm

Conversation

@DanBmh
Copy link
Copy Markdown
Contributor

@DanBmh DanBmh commented Mar 3, 2025

Use only image contour for camera matrix undistortion.
For inner and outer rectangles of the undistorted image only the image border should be necessary when standard distortion models are used. Using inner image points notably slows down the process since more points need to be undistorted (81 vs 32).

@DanBmh
Copy link
Copy Markdown
Contributor Author

DanBmh commented Mar 3, 2025

In my opinion it should also be possible to reduce the N=9 to N=3

@asmorkalov
Copy link
Copy Markdown
Contributor

The idea looks good in general, but I propose to refactor a bit:

  • Use several loops to iterate through borders only.
  • Add a comment with assumption before the loops.

@DanBmh
Copy link
Copy Markdown
Contributor Author

DanBmh commented Mar 10, 2025

The problem with using several loops is that it reduces readability for a very low computational benefit (and i'm not sure if the compiler is already able to optimize the current solution). Below would be an approach without the continue. Which version do you prefer?

int k = 0;
for (int x = 0; x < N; ++x)
    pts[k++] = Point2d((double)x*(imgSize.width-1)/(N-1), 0);
for (int x = 0; x < N; ++x)
    pts[k++] = Point2d( (double)x*(imgSize.width-1)/(N-1), imgSize.height - 1);
for (int y = 1; y < N - 1; ++y)
    pts[k++] = Point2d(0, (double)y*(imgSize.height-1)/(N-1));
for (int y = 1; y < N - 1; ++y)
    pts[k++] = Point2d(imgSize.width - 1, (double)y*(imgSize.height-1)/(N-1);

undistortPoints(_pts, _pts, _cameraMatrix, _distCoeffs, R, newCameraMatrix);

double iX0=-FLT_MAX, iX1=FLT_MAX, iY0=-FLT_MAX, iY1=FLT_MAX;
double oX0=FLT_MAX, oX1=-FLT_MAX, oY0=FLT_MAX, oY1=-FLT_MAX;
// find the inscribed rectangle.
// the code will likely not work with extreme rotation matrices (R) (>45%)
k = 0;
for (int x = 0; x < N; ++x) {
    Point2d p = pts[k++];
    oX0 = MIN(oX0, p.x);  
    oX1 = MAX(oX1, p.x);
    oY0 = MIN(oY0, p.y);  
    oY1 = MAX(oY1, p.y);
    iY0 = MAX(iY0, p.y);
}
for (int x = 0; x < N; ++x) {
    Point2d p = pts[k++];
    oX0 = MIN(oX0, p.x);  
    oX1 = MAX(oX1, p.x);
    oY0 = MIN(oY0, p.y);  
    oY1 = MAX(oY1, p.y);
    iY1 = MIN(iY1, p.y); 
}
for (int y = 1; y < N - 1; ++y) {
    Point2d p = pts[k++];
    oX0 = MIN(oX0, p.x); 
    oX1 = MAX(oX1, p.x);
    oY0 = MIN(oY0, p.y); 
    oY1 = MAX(oY1, p.y);
    iX0 = MAX(iX0, p.x);
}
for (int y = 1; y < N - 1; ++y) {
    Point2d p = pts[k++];
    oX0 = MIN(oX0, p.x);
    oX1 = MAX(oX1, p.x);
    oY0 = MIN(oY0, p.y);
    oY1 = MAX(oY1, p.y);
    iX1 = MIN(iX1, p.x);
}

@asmorkalov asmorkalov self-requested a review March 10, 2025 14:18
@asmorkalov asmorkalov self-assigned this Mar 10, 2025
@asmorkalov asmorkalov merged commit 6fb082a into opencv:4.x Mar 11, 2025
28 checks passed
@asmorkalov asmorkalov mentioned this pull request Mar 11, 2025
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.

2 participants