-
Notifications
You must be signed in to change notification settings - Fork 938
Description
I'm using cv2.undistort, but it crops the image. I'd like to have all the undistorted image, so that the undistorted size is bigger than the original one, like this:
See this post on stackoverflow, particularly the responses for Josep Bosch and andremkeller:
https://stackoverflow.com/questions/18742679/how-to-get-all-undistorted-image-with-opencv
I have tried to emulate the code andrewmkeller posted, using Python instead of C++, with some minor changes based on Josh Bosch's response. The result is the following:
#!/usr/bin/env` python
import cv2
import numpy as np
def loadUndistortedImage(fileName):
# load image
image = cv2.imread(fileName)
#print(image)
# set distortion coeff and intrinsic camera matrix (focal length, centerpoint offset, x-y skew)
cameraMatrix = np.array([[894.96803896,0,470.38713516],[0,901.32629374,922.41232898], [0,0,1]])
distCoeffs = np.array([[-0.340671222,0.110426603,-.000867987573,0.000189669273,-0.0160049526]])
# setup enlargement and offset for new image
y_shift = 60 #experiment with
x_shift = 70 #experiment with
imageShape = image.shape #image.size
print(imageShape)
imageSize = (int(imageShape[0])+2*y_shift, int(imageShape[1])+2*x_shift, 3)
print(imageSize)
# create a new camera matrix with the principal point offest according to the offset above
newCameraMatrix, validPixROI = cv2.getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize,
1)
#newCameraMatrix = cv2.getDefaultNewCameraMatrix(cameraMatrix, imageSize, True) # imageSize, True
# create undistortion maps
R = np.array([[1,0,0],[0,1,0],[0,0,1]])
map1, map2 = cv2.initUndistortRectifyMap(cameraMatrix, distCoeffs, R, newCameraMatrix, imageSize,
cv2.CV_16SC2)
# remap
outputImage = cv2.remap(image, map1, map2, INTER_LINEAR)
#save output image as file with "FIX" appened to name - only works with .jpg files at the moment
index = filename.find('.jpg')
fixed_filename = filename[:index] +'_undistorted'+fileName[index:]
cv2.imwrite(fixed_filename, outputImage)
cv2.imshow('fix_img',outputImage)
cv2.waitKey(0)
return
#Undistort the images, then save the restored images
`loadUndistortedImage('./calib/WIN_20200626_11_29_16_Pro.jpg')
This seemed good to me, but then problems came up when trying to use cv2.getOptimalNewCameraMatrix or cv2.getDefaultNewCameraMatrix and cv2.initUndistortRectifyMap. I kept getting told that 'the argument takes exactly 2 arguments (3 given)' even though I am putting the parameters as specified in their documentation here: https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html https://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html
I can remove the error from "...getDefault..." if I remove the optional params, but I'd rather not do that.
Stacktrace:
Traceback (most recent call last):
File ".\main.py", line 46, in <module>
loadUndistortedImage('./<image file name>.jpg')
File ".\main.py", line 27, in loadUndistortedImage
newCameraMatrix, validPixROI = cv2.getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1)
TypeError: function takes exactly 2 arguments (3 given)