通过在 OPENCV 和实时视频中使用固有矩阵和畸变系数来进行相机校准
Doing camera calibration by having intrinsic matrix and distortion coefficients in OPENCV and in real-time video
我已经使用opencv提供的标定代码标定了我的相机,一切正常!我还可以通过使用 Python.
中编写的代码应用参数来消除任何我想要的图像失真
import numpy as np
import cv2
# copy parameters to arrays
K = np.array([[385.58130632872212, 0, 371.50000000000000], [0, 385.58130632872212, 236.50000000000000], [0, 0, 1]])
d = np.array([-0.27057628187805571, 0.10522881965331317, 0, 0, 0]) # just use first two terms (no translation)
# read one of your images
img = cv2.imread("C:\Users\ROS\Documents\Python\VCSBC2.jpg")
h, w = img.shape[:2]
# undistort
newcamera, roi = cv2.getOptimalNewCameraMatrix(K, d, (w,h), 0)
newimg = cv2.undistort(img, K, d, None, newcamera)
cv2.imwrite("original.jpg", img)
cv2.imwrite("undistorted.jpg", newimg)
但问题是我真的不知道如何在实时传输期间消除图像失真。我正在使用 TCP/IP 协议从我的相机获取图像,我可以从它里面 运行 东西,但我不知道我应该如何插入矩阵和参数那里是为了实时获得未失真的图像。有没有人可以给我一些启发?
谢谢。
如果没有看到用于从相机中提取图像的代码,很难给出建议。一般来说,如果你的帧率要求足够低,你可以从相机中获取像素缓冲区,将它们复制到 cv 图像中并应用 undistort。
在更高的帧速率下,cv undistort 可能证明太慢,因为它在双线性(或三线性)插值步骤之前计算每个像素的非线性变换。
然后你有两个选择
预计算扭曲贴图。这些是缓存上述非线性计算的矩阵(在两个通道中,分别是水平和垂直方向),并为每一帧重用它。这种方法的 OpenCV implementation 有点蹩脚,因为它需要与输入图像大小相同的变换图,当失真在任何地方都足够平滑和适度以至于人们可以对其进行下采样时,这是一种浪费。在这些情况下,对于足够大的图像和帧速率,全尺寸地图中的查找是浪费的并且可能成为瓶颈。如果使用下采样滚动他们自己的扭曲图实现,则必须注意采样率足够高以保证在任何地方(尤其是在图像边界处)正确失真。这通常会导致扭曲贴图 "denser" 超过所需的效果,因为图像边界处的失真通常比中心处的失真更陡峭。然而,它是一种简单且通常 "good enough" 的方法,许多专业应用程序广泛使用它(例如 Shake)。
使用非均匀分段线性近似。这里的想法是使用四叉树细分图像 canvas 直到近似每个四边形中的非线性扭曲的误差,使用由扭曲四边形本身的顶点引起的单应性,小于阈值(例如 1 /10 个像素)。优点是线性变形四边形很快并且可以在插值循环内实现。在足够适度的失真情况下,该技术仅使用几级四叉树,并且使用图形库(例如 OpenGL)的直接实现很容易在高分辨率下实现高帧率。我个人大约从十年前开始使用这种技术,并且可以在高清视频分辨率下轻松地以 60FPS 的速度对图像进行去扭曲。
我已经使用opencv提供的标定代码标定了我的相机,一切正常!我还可以通过使用 Python.
中编写的代码应用参数来消除任何我想要的图像失真import numpy as np
import cv2
# copy parameters to arrays
K = np.array([[385.58130632872212, 0, 371.50000000000000], [0, 385.58130632872212, 236.50000000000000], [0, 0, 1]])
d = np.array([-0.27057628187805571, 0.10522881965331317, 0, 0, 0]) # just use first two terms (no translation)
# read one of your images
img = cv2.imread("C:\Users\ROS\Documents\Python\VCSBC2.jpg")
h, w = img.shape[:2]
# undistort
newcamera, roi = cv2.getOptimalNewCameraMatrix(K, d, (w,h), 0)
newimg = cv2.undistort(img, K, d, None, newcamera)
cv2.imwrite("original.jpg", img)
cv2.imwrite("undistorted.jpg", newimg)
但问题是我真的不知道如何在实时传输期间消除图像失真。我正在使用 TCP/IP 协议从我的相机获取图像,我可以从它里面 运行 东西,但我不知道我应该如何插入矩阵和参数那里是为了实时获得未失真的图像。有没有人可以给我一些启发?
谢谢。
如果没有看到用于从相机中提取图像的代码,很难给出建议。一般来说,如果你的帧率要求足够低,你可以从相机中获取像素缓冲区,将它们复制到 cv 图像中并应用 undistort。
在更高的帧速率下,cv undistort 可能证明太慢,因为它在双线性(或三线性)插值步骤之前计算每个像素的非线性变换。
然后你有两个选择
预计算扭曲贴图。这些是缓存上述非线性计算的矩阵(在两个通道中,分别是水平和垂直方向),并为每一帧重用它。这种方法的 OpenCV implementation 有点蹩脚,因为它需要与输入图像大小相同的变换图,当失真在任何地方都足够平滑和适度以至于人们可以对其进行下采样时,这是一种浪费。在这些情况下,对于足够大的图像和帧速率,全尺寸地图中的查找是浪费的并且可能成为瓶颈。如果使用下采样滚动他们自己的扭曲图实现,则必须注意采样率足够高以保证在任何地方(尤其是在图像边界处)正确失真。这通常会导致扭曲贴图 "denser" 超过所需的效果,因为图像边界处的失真通常比中心处的失真更陡峭。然而,它是一种简单且通常 "good enough" 的方法,许多专业应用程序广泛使用它(例如 Shake)。
使用非均匀分段线性近似。这里的想法是使用四叉树细分图像 canvas 直到近似每个四边形中的非线性扭曲的误差,使用由扭曲四边形本身的顶点引起的单应性,小于阈值(例如 1 /10 个像素)。优点是线性变形四边形很快并且可以在插值循环内实现。在足够适度的失真情况下,该技术仅使用几级四叉树,并且使用图形库(例如 OpenGL)的直接实现很容易在高分辨率下实现高帧率。我个人大约从十年前开始使用这种技术,并且可以在高清视频分辨率下轻松地以 60FPS 的速度对图像进行去扭曲。