-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Closed
Labels
Description
System information (version)
- OpenCV => 3.3.0-dev
- both in C++ and Python3
Detailed description
We are using omnidir module to correct wide angle fisheye effect on image data.
We first used cv::omnidir::calibrate to get a valid camera model.
We then used this model to undistort both images and points.
We found that applying undistortion methods with exact same parameters on images and points gives different results.
After investigation we think a bug exists in the undistortPoints method.
Steps to reproduce
Code to reproduce (fixed to be working, thanks to @whplh).
# import of modules
import numpy as np
import cv2
import matplotlib.pyplot as plt
#%matplotlib inline
# in/out image size
height, width = (1520, 2048)
# definition of camera model's parameters
K = np.array([[922.676, -6.87115, 1028.38], [0, 921.053, 718.469], [0, 0, 1]], np.float)
D = np.array([[-0.32628, 0.117317, 0.00124854, 0.000268858]], np.float)
X = np.array([[0.772963]], np.float)
# exposes K parameters
(fx, s, cx), (_, fy, cy), _ = K
# Build a list of 'known' distorted points
nPointsPerCirle = 20
fisheyeRadius = 700
circleRadiuses = range(0, fisheyeRadius, 100)
angle = 2*np.pi * np.array([*range(nPointsPerCirle)], np.float) / nPointsPerCirle
distorted_points = np.vstack((
np.vstack((cx + r * np.cos(angle), cy + r * np.sin(angle))).T
for r in circleRadiuses
))
# Build a distorted image with that known points on it
distorted_frame = np.zeros((height, width, 3), np.uint8)
cv2.circle(distorted_frame, (int(cx), int(cy)), fisheyeRadius, (255,255,255), -1)
# place points
for distorted_point in distorted_points.astype(int):
cv2.circle(distorted_frame, tuple(distorted_point), 5, (0,0,255), -1)
# undistort image using omnidir
undistorted_frame = cv2.omnidir.undistortImage(distorted_frame, K, D, X, 1, np.eye(3))
# undistort points
undistorted_points = cv2.omnidir.undistortPoints(
np.array([distorted_points.tolist()], np.float),
K, D, X, np.eye(3))
x,y = undistorted_points.reshape(-1,2).T
undistorted_points = K.dot(np.vstack((x,y,np.ones_like(x)))).T[:,:2]
# print undistorted points ontop of undistorted image
for undistorted_point in undistorted_points.astype(int):
cv2.circle(undistorted_frame, tuple(undistorted_point), 5, (255,0,0), 3)
# show result
out_frame = np.hstack((distorted_frame, undistorted_frame))
plt.figure(figsize=(np.array(out_frame.shape[:2]) / 100).tolist())
plt.imshow(cv2.cvtColor(out_frame, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.show()
alalek, flyaudio and hushunda