Radial undistortion model

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?

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)

do you think screenshotting some source code is a good idea? you can edit your post.

Sorry first time posting and I didn’t know how I could include my code.

ah, interesting.

so you’d like to apply a scale factor then? or calculate a larger dsize and shift the image center to match?

I think a scale factor. but I am not sure how to do it.