Fisheye undistortion

Hi,

I managed to get the undistortion of my camera working in Python. I am now trying to convert it into C++ using the same logic and same parameters, but fail to do so.

The k_mat and d_mat are the same in Python and C++, I can see that the resulting camera matrix is also the same. But then map_x and map_y end up as being different and my resulting image is not looking right at all.

For reference, here is my prototype C++ code:

float kmat_values[3][3] = {{1.51865043e+03, 0.00000000e+00, 9.97723183e+02},
                            {0.00000000e+00, 1.52017147e+03, 5.41360776e+02},
                            {0.00000000e+00, 0.00000000e+00, 1.00000000e+00}};

float dmat_values[4][1] = {{-0.19509397},
                            { 0.07629731},
                            {-0.18873016},
                            { 0.17534094}};

float balance = 0.0;
Size video_size(1920, 1080);

Mat kmat(3, 3, CV_32FC1, kmat_values);
Mat dmat(4, 1, CV_32FC1, dmat_values);

Mat mapx, mapy, camera;

void init() {
    Mat eye = Mat::eye(3, 3, CV_32FC1);

    fisheye::estimateNewCameraMatrixForUndistortRectify(
        kmat,
        dmat,
        video_size,
        eye,
        camera,
        balance
    );

    initUndistortRectifyMap(
        kmat,
        dmat,
        eye,
        camera,
        video_size,
        CV_32FC1,
        mapx,
        mapy
    );
}

void undistort_image(Mat &frame, Mat &undistorted) {
    remap(frame, undistorted, mapx, mapy, INTER_LINEAR, BORDER_CONSTANT);
}

I have left the main along with the reading and writing of the images out but can include them if required.

You will find the result image below (as a new user I can only include one media, I can try to include the raw image in a reply post if required):

Any help would be greatly appreciated. I have tried playing around with different types (e.g. CV_16SC1 etc) but don’t see any difference.

Thanks,
Antoine

please provide the Python code as well, for comparison.

I don’t see the issue yet. current bet: mismatch between arguments and parameters.

Hi @crackwitz ,

Thanks for replying.

The python code is as follows:

import cv2
import numpy as np

DIM = (1920,1080)

k_mat = np.array(
    [[1.51865043e+03, 0.00000000e+00, 9.97723183e+02],
    [0.00000000e+00, 1.52017147e+03, 5.41360776e+02],
    [0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]
)

d_mat = np.array(
    [[-0.19509397],
    [ 0.07629731],
    [-0.18873016],
    [ 0.17534094]]
)

balance = 0.0

camera_mat = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(
    k_mat, d_mat, DIM, np.eye(3), balance=balance
)

mapx, mapy = cv2.fisheye.initUndistortRectifyMap(
    k_mat, d_mat, np.eye(3), camera_mat, DIM, cv2.CV_32FC1
)

def undistort(img):
    dst = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)
    return dst

cap = cv2.VideoCapture("input.jpeg")
ret, img = cap.read()

undistorted = undistort(img)
cv2.imwrite("python_undistorted.jpeg", undistorted)

And the image is undistorted properly:

I managed to find out what was wrong: I had a namespace issue. I was using the initUndistortRectifyMap function from a different scope, changing that line to fisheye::initUndistortRectifyMap fixed the problem.
Thanks anyways!
Cheers

1 Like