I have calibrated a fisheye camera. To undistort image, I use initUndistortRectifyMap()
followed by remap()
. In initUndistortRectifyMap()
I can give a rotation matrix in argument in order to rotate the undistorted image on a specific part of the fisheye image. I would like to know if there is a way to find automatically the rotation vector so that given a specific pixel position in the fisheye, the undistorted image in centered on this pixel. It could be used to track someone in the fisheye image and then undistort this person for algorithms which need an undistorted image.
This the code I'm using to undistort the image.
```
def undistort(self, img, zoom=1.0, rot_vec=np.eye(3)):
"""
Undistort an image from a fisheye camera
:param img: The distorted image (numpy array).
:param alpha: (optional) Free scaling parameter between 0 (when all the pixels in the undistorted image are valid) and 1 (when all the source image pixels are retained in the undistorted image).
:param zoom: (optional) Zoom factor in the undistorted images.
:param rot_vec: (optional) Rotation vector (alpha, beta, gamma) used to rotate view of undistorted fisheye image.
:return: The undistorted image.
"""
t0 = timeit.default_timer()
h, w = img.shape[:2] # the dimension of input image to un-distort
assert w / h == self._dims[0] / self._dims[1], "Image to undistort needs to have same aspect " \
"ratio as the ones used in calibration"
if self._cam_type == "fish_eye":
scaled_K = self._K * w / h # The values of K is to scale with image dimension.
scaled_K[0, 0] *= zoom
scaled_K[1, 1] *= zoom
scaled_K[2, 2] = 1.0 # Except that K[2][2] is always 1.0
R = cv2.Rodrigues(rot_vec)[0]
# self._K is the camera matrix end self._D the distortion coefficients
map1, map2 = cv2.fisheye.initUndistortRectifyMap(self._K, self._D, R, scaled_K, (w, h), cv2.CV_16SC2)
img_undistorted = cv2.remap(img, map1, map2, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
return img_undistorted
```