I am trying to apply radial undistortion model to my input image and my code is working. However the output image does not contain all the pixels from the original image and is being cropped to exact same size as the original image. Can you please help me to modify the code so the output (undistorted image) contains all the pixels from the original image?
Thanks.
import cv2
import numpy as np
def apply_radial_undistortion(image, k1, k2):
height, width = image.shape[:2]
cx, cy = width / 2, height / 2
# Generate the normalized coordinates
x, y = np.meshgrid(np.arange(width), np.arange(height))
nx = (x - cx) / cx
ny = (y - cy) / cy
r_squared = nx**2 + ny**2
# Apply the inverse of the radial distortion model
undistorted_r_squared = np.sqrt(1 + (k1 + k2 * r_squared) * r_squared)
undistorted_x = nx / undistorted_r_squared
undistorted_y = ny / undistorted_r_squared
# Map the undistorted coordinates back to the original image
undistorted_x = undistorted_x * cx + cx
undistorted_y = undistorted_y * cy + cy
# Determine the output size based on the maximum and minimum undistorted coordinates
min_undistorted_x = np.min(undistorted_x)
max_undistorted_x = np.max(undistorted_x)
min_undistorted_y = np.min(undistorted_y)
max_undistorted_y = np.max(undistorted_y)
output_width = int(np.ceil(max_undistorted_x - min_undistorted_x))
output_height = int(np.ceil(max_undistorted_y - min_undistorted_y))
# Create a new image with the undistorted size
output = np.zeros((output_height, output_width, 3), dtype=np.uint8)
# Shift the undistorted coordinates to align with the output size
shifted_undistorted_x = undistorted_x - min_undistorted_x
shifted_undistorted_y = undistorted_y - min_undistorted_y
# Remap the image using the undistorted coordinates
output = cv2.remap(image, shifted_undistrted_x.astype(np.float32), shifted_undistorted_y.astype(np.float32), cv2.INTER_LINEAR)
return output
# Load the image
image_path = '1.jpg'
image = cv2.imread(image_path)
# Define the radial distortion parameters (adjust accordingly)
k1 = 0.1
k2 = 0.2
# Apply the radial undistortion model
undistorted_image = apply_radial_undistortion(image, k1, k2)
# Save the undistorted image
output_path = '2.jpg'
cv2.imwrite(output_path, undistorted_image)
# Display the original and undistorted images
cv2.imshow('Original Image', image)
cv2.imshow('Undistorted Image', undistorted_image)
cv2.waitKey(0)
cv2.destroyAllWindows()