计算机视觉:Opencv图像去畸变
计算机视觉:Opencv图像去畸变
针孔相机模型图像去畸变
针对畸变参数,k1,k2,k3,k4描述径向的畸变参数,p1,p2描述切向的畸变参数,一般k4不使用,默认为0.
方法一
方法一是使用cv2.undistort函数,undistort函数依据相机内参与畸变系数対原图像进行去畸变。
import cv2
import numpy as np
parameter_mapping = {
# 内参
'K': [[560.377864062484, 0.0, 653.920208824032], [0.0, 560.333488463768, 405.051274966661],
[0.0, 0.0, 1.0]],
# 畸变系数( k1 , k2 , p1 , p2 , k3 )
'D': [-0.315795863414683, 0.132439325545726, 3.30224273178591e-05, -0.000236840010193784, -0.0289107949906846]
}
if __name__ == '__main__':
image_file = './origin_img.jpg'
img = cv2.imdecode(np.fromfile(image_file, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
undistortion_img = cv2.undistort(img, np.array(parameter_mapping["K"]),
np.array(parameter_mapping["D"]), None, None)
cv2.imencode('.jpg', undistortion_img)[1].tofile('./undistortion_img.jpg')
方法二
方法二是使用cv2.initUndistortRectifyMap和cv2.remap函数,initUndistortRectifyMap函数用于计算原图像与去畸变图像的转换关系,remap函数可以将一幅图像中某位置的像素放置到另一个图片指定位置。
import cv2
import numpy as np
parameter_mapping = {
# 内参
'K': [[560.377864062484, 0.0, 653.920208824032], [0.0, 560.333488463768, 405.051274966661],
[0.0, 0.0, 1.0]],
# 畸变系数( k1 , k2 , p1 , p2 , k3 )
'D': [-0.315795863414683, 0.132439325545726, 3.30224273178591e-05, -0.000236840010193784, -0.0289107949906846]
}
if __name__ == '__main__':
image_file = './origin_img.jpg'
img = cv2.imdecode(np.fromfile(image_file, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
mapx,mapy = cv2.initUndistortRectifyMap(np.array(parameter_mapping["K"]), np.array(parameter_mapping["D"]), None, None, (img.shape[1],img.shape[0]),cv2.CV_16SC2)
undistortion_img = cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
cv2.imencode('.jpg', undistortion_img)[1].tofile('./undistortion_img.jpg')
区别与联系
undistort函数是initUndistortRectifyMap和remap两个函数的合并。
在硬件设备上运行时,摄像头实时对原图像进行去畸变,使用undistort函数占用cpu内核较高,而使用initUndistortRectifyMap和remap的方法,初始化时率先计算出重映射参数并保存下来,然后针对每一帧图像直接使用之前计算好的重映射参数进行remap映射,计算复杂度比方法一小很多。
鱼眼相机模型图像去畸变
在此采用的是cv::fisheye描述方法,畸变参数只有四个:k1,k2,k3,k4,这是opencv专门为鱼眼相机创建的模型,也对应着kalibr中的pinhole-equidistant模型。鱼眼相机模型去畸变后图像左右上下边缘可能存在黒框,需要进一步裁切处理。
方法一
方法一是使用cv2.fisheye.undistortImage函数。
import cv2
import numpy as np
parameter_mapping = {
# 内参
'K': [[562.8536266451736, 0.0, 652.0363818527527], [0.0, 562.7074689373112, 405.06204162772434],
[0.0, 0.0, 1.0]],
# 新的内参,默认与内参相同,如果有平移缩放,则可通过cv::getOptimalNewCameraMatrix()函数计算
'new_K': [[298.6393797450104, 0.0, 659.9713311562739], [0.0, 298.56183125788215, 404.8096582172302],
[0.0, 0.0, 1.0]],
# 畸变系数( k1 , k2 , k3 , k4)
'D': [-0.008989658783934219, 0.02224293904563013, -0.0145636811902354, 0.005863283995426509]
}
if __name__ == '__main__':
image_file = './origin_img.jpg'
img = cv2.imdecode(np.fromfile(image_file, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
undistortion_img = cv2.fisheye.undistortImage(img, np.array(parameter_mapping["K"]), np.array(parameter_mapping["D"]), np.eye(3), np.array(parameter_mapping["new_K"]), (img.shape[1],img.shape[0]))
cv2.imencode('.jpg', undistortion_img)[1].tofile('./undistortion_img.jpg')
方法二
方法二是使用cv2.fisheye.initUndistortRectifyMap和cv2.remap函数。
import cv2
import numpy as np
parameter_mapping = {
# 内参
'K': [[562.8536266451736, 0.0, 652.0363818527527], [0.0, 562.7074689373112, 405.06204162772434],
[0.0, 0.0, 1.0]],
# 新的内参,默认与内参相同,如果有平移缩放,则可通过cv::getOptimalNewCameraMatrix()函数计算
'new_K': [[298.6393797450104, 0.0, 659.9713311562739], [0.0, 298.56183125788215, 404.8096582172302],
[0.0, 0.0, 1.0]],
# 畸变系数( k1 , k2 , k3 , k4)
'D': [-0.008989658783934219, 0.02224293904563013, -0.0145636811902354, 0.005863283995426509]
}
if __name__ == '__main__':
image_file = './origin_img.jpg'
img = cv2.imdecode(np.fromfile(image_file, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
mapx,mapy = cv2.fisheye.initUndistortRectifyMap(np.array(parameter_mapping["K"]), np.array(parameter_mapping["D"]), np.eye(3), np.array(parameter_mapping["new_K"]), (img.shape[1],img.shape[0]),cv2.CV_16SC2)
undistortion_img = cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
cv2.imencode('.jpg', undistortion_img)[1].tofile('./undistortion_img.jpg')
区别与联系
undistortImage函数是initUndistortRectifyMap和remap两个函数的合并。
在硬件设备上运行时,摄像头实时对原图像进行去畸变,使用undistortImage函数占用cpu内核较高,而使用initUndistortRectifyMap和remap的方法,初始化时率先计算出重映射参数并保存下来,然后针对每一帧图像直接使用之前计算好的重映射参数进行remap映射,计算复杂度比方法一小很多。
参考文献
https://zhuanlan.zhihu.com/p/137053640
https://blog.csdn.net/Thomson617/article/details/103987952
更多推荐
所有评论(0)