我已经使用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 协议(protocol)从我的相机获取图像,我可以从它内部运行东西,但我不知道我应该如何插入矩阵和参数以获得不失真实时图像。有没有人可以给我一些启发?
谢谢。
最佳答案
如果没有看到用于从相机中提取图像的代码,很难给出建议。一般来说,如果您的帧速率要求足够低,您可以从相机中获取像素缓冲区,将它们复制到 cv 图像中并应用 undistort。
在更高的帧速率下,cv undistort 可能证明太慢,因为它在双线性(或三线性)插值步骤之前计算每个像素的非线性变换。
然后你有两个选择
预先计算扭曲贴图。这些是缓存上述非线性计算的矩阵(在两个 channel 中,分别是水平和垂直方向),并为每一帧重用它。 OpenCV implementation这种方法有点蹩脚,因为它需要与输入图像大小相同的变换图,当失真在任何地方都平滑且适度到可以通过下采样来逃脱时,这是一种浪费。在这些情况下,对于足够大的图像和帧速率,全尺寸 map 中的查找是浪费的并且可能成为瓶颈。如果使用下采样滚动他们自己的扭曲图实现,则必须注意采样率足够高以保证在任何地方(尤其是在图像边界处)正确失真。这通常会产生扭曲贴图比它们需要的“更密集”的效果,因为图像边界处的失真通常比中心处更陡峭。然而,这是一种简单且通常“足够好”的方法,许多专业应用程序广泛使用它(例如 Shake)。
使用非均匀分段线性近似。这里的想法是使用四叉树 segmentation 图像 Canvas ,直到近似每个四边形中的非线性扭曲的误差,使用由扭曲四边形本身的顶点引起的单应性,小于阈值(例如 1/10像素)。优点是线性变形四边形很快并且可以在插值循环内实现。在足够适度的失真情况下,该技术仅使用几级四叉树,并且使用图形库(例如 OpenGL)的直接实现很容易在高分辨率下实现高帧率。我个人大约从十年前开始使用这种技术,并且可以在高清视频分辨率下轻松地以 60FPS 的速度对图像进行去扭曲。
关于python - 通过在 OPENCV 和实时视频中使用固有矩阵和畸变系数来进行相机校准,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28479678/