你好
我正在尝试从鱼眼扭曲的图像中获得向下的视图。
当前相机方向如下所示。如果从左视图看,相机向下看,
40deg
从前轴朝向下轴。如果从俯视图看,相机相对于前轴向左倾斜 30deg
。
我制作了一个python3脚本,但对输出不满意。我认为我对相机方向的解释有问题。
import cv2
import numpy as np
rollDeg = 50
pitchDeg = 30
# Camera calibration parameters
K = np.array([[413.4459003089536, 0.0, 625.4657090067509],
[0.0, 414.5602416017697, 393.99252903112915],
[0.0, 0.0, 1.0]])
D = np.array([[0.2422953376828772],
[0.5059306403608751],
[-0.48731143899233426],
[0.17754105229960523]])
# Estimate a new camera matrix optimized for undistortion
new_K = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(K, D, (1280, 720), np.eye(3), balance=1, new_size=(1280, 720), fov_scale=1)
# Initial values for new_K parameters
fx_init = 230
fy_init = 230
cx_init = 1280//2
cy_init = 720//2
# Function to update undistorted image
def update_image():
# Update new_K matrix based on trackbar values
rollDeg = cv2.getTrackbarPos('roll', 'img')
pitchDeg = cv2.getTrackbarPos('pitch', 'img')
new_K[0, 0] = cv2.getTrackbarPos('fx', 'img')
new_K[1, 1] = cv2.getTrackbarPos('fy', 'img')
new_K[0, 2] = cv2.getTrackbarPos('cx', 'img')
new_K[1, 2] = cv2.getTrackbarPos('cy', 'img')
roll = rollDeg * np.pi / 180
pitch = -pitchDeg * np.pi / 180
# ******** I am doubtful about these couple of lines **********
# Rotation matrices for roll (rotX) and pitch (rotY)
rotX = np.array([[1, 0, 0],
[0, np.cos(roll), -np.sin(roll)],
[0, np.sin(roll), np.cos(roll)]])
rotY = np.array([[np.cos(pitch), 0, np.sin(pitch)],
[0, 1, 0],
[-np.sin(pitch), 0, np.cos(pitch)]])
# Combined rotation matrix
rotation = rotX @ rotY
# Calculate rotated intrinsic matrix
K_rotated = rotation @ K
# Generate undistortion map
mapx, mapy = cv2.fisheye.initUndistortRectifyMap(K_rotated, D, rotation, new_K, (1280, 720), cv2.CV_16SC2)
# ******** **********
# Remap input image using undistortion map
undistorted_image = cv2.remap(input_image, mapx, mapy, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
# Display undistorted image
cv2.imshow('img', undistorted_image)
#cv2.imwrite('undistortedImg.jpg', undistorted_image)
# Load input image
input_image = cv2.imread("distortedImg.png")
# Create named window and trackbars
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.createTrackbar('roll', 'img', int(rollDeg), 89, lambda x: update_image())
cv2.createTrackbar('pitch', 'img', int(pitchDeg), 89, lambda x: update_image())
cv2.createTrackbar('fx', 'img', fx_init, 500, lambda x: update_image())
cv2.createTrackbar('fy', 'img', fy_init, 500, lambda x: update_image())
cv2.createTrackbar('cx', 'img', cx_init, 1920, lambda x: update_image())
cv2.createTrackbar('cy', 'img', cy_init, 1080, lambda x: update_image())
# Initialize undistorted image
update_image()
# Wait for key press to exit
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2
import numpy as np
rollDeg = 50
pitchDeg = 30
# Camera calibration parameters
K = np.array([[413.4459003089536, 0.0, 625.4657090067509],
[0.0, 414.5602416017697, 393.99252903112915],
[0.0, 0.0, 1.0]])
D = np.array([[0.2422953376828772],
[0.5059306403608751],
[-0.48731143899233426],
[0.17754105229960523]])
# Estimate a new camera matrix optimized for undistortion
new_K = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(K, D, (1280, 720), np.eye(3), balance=1, new_size=(1280, 720), fov_scale=1)
# Initial values for new_K parameters
fx_init = 82
fy_init = 82
cx_init = 1000
cy_init = 600
# Function to update undistorted image
def update_image():
# Update new_K matrix based on trackbar values
rollDeg = cv2.getTrackbarPos('roll', 'img')
pitchDeg = cv2.getTrackbarPos('pitch', 'img')
new_K[0, 0] = cv2.getTrackbarPos('fx', 'img')
new_K[1, 1] = cv2.getTrackbarPos('fy', 'img')
new_K[0, 2] = cv2.getTrackbarPos('cx', 'img')
new_K[1, 2] = cv2.getTrackbarPos('cy', 'img')
roll = rollDeg * np.pi / 180
pitch = -pitchDeg * np.pi / 180
# Rotation matrices for roll (rotX) and pitch (rotY)
rotX = np.array([[1, 0, 0],
[0, np.cos(roll), -np.sin(roll)],
[0, np.sin(roll), np.cos(roll)]])
# rotY = np.array([[np.cos(pitch), 0, np.sin(pitch)],
# [0, 1, 0],
# [-np.sin(pitch), 0, np.cos(pitch)]])
rotZ = np.array([[np.cos(pitch), -np.sin(pitch), 0],
[np.sin(pitch), np.cos(pitch), 0],
[0, 0, 1]])
# Combined rotation matrix
rotation = rotZ @ rotX
# Calculate rotated intrinsic matrix
# K_rotated = rotation @ K
# Generate undistortion map
mapx, mapy = cv2.fisheye.initUndistortRectifyMap(K, D, rotation, new_K, (1280, 720), cv2.CV_16SC2)
# Remap input image using undistortion map
undistorted_image = cv2.remap(input_image, mapx, mapy, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
# Display undistorted image
cv2.imshow('img', undistorted_image)
# cv2.imshow('img', cv2.rotate(undistorted_image, cv2.ROTATE_90_COUNTERCLOCKWISE))
# Load input image
input_image = cv2.imread("distortedImg.png")
# Create named window and trackbars
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.createTrackbar('roll', 'img', int(rollDeg), 89, lambda x: update_image())
cv2.createTrackbar('pitch', 'img', int(pitchDeg), 89, lambda x: update_image())
cv2.createTrackbar('fx', 'img', fx_init, 500, lambda x: update_image())
cv2.createTrackbar('fy', 'img', fy_init, 500, lambda x: update_image())
cv2.createTrackbar('cx', 'img', cx_init, 1920, lambda x: update_image())
cv2.createTrackbar('cy', 'img', cy_init, 1080, lambda x: update_image())
# Initialize undistorted image
update_image()
# Wait for key press to exit
cv2.waitKey(0)
cv2.destroyAllWindows()