我有一个鱼眼镜头:
我想不扭曲它。我应用 FOV 模型:
rd = 1 / ω * arctan (2 * ru * tan(ω / 2)) //Equation 13
ru = tan(rd * ω) / 2 / tan(ω / 2) //Equation 14
如 INRIA 论文“直线必须是直的” https://hal.inria.fr/inria-00267247/document的等式 (13) 和 (14) 中所示。
代码实现如下:
Point2f distortPoint(float w, float h, float cx, float cy, float omega, Point2f input) {
//w = width of the image
//h = height of the image
//cx = center of the lens in the image, aka w/2
//cy = center of the lens in the image, aka h/2
Point2f tmp = new Point2f();
//We normalize the coordinates of the point
tmp.x = input.x / w - cx / w;
tmp.y = input.y / h - cy / h;
//We apply the INRIA key formula (FOV model)
double ru = sqrt(tmp.x * tmp.x + tmp.y * tmp.y);
double rd = 1.0f / omega * atan(2.0f * ru * tan(omega / 2.0f));
tmp.x *= rd / ru;
tmp.y *= rd / ru;
//We "un-normalize" the point
Point2f ret = new Point2f();
ret.x = (tmp.x + cx / w) * w;
ret.y = (tmp.y + cy / h) * h;
return ret;
}
然后我使用了 OpenCV 重映射函数:
//map_x and map_y are computed with distortPoint
remap(img, imgUndistorted, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
我设法从镜头制造商那里获得了失真模型。它是一个 image_height 表,它是视场角的函数:
Field angle(deg) Image Height (mm)
0 0
1 height1
2 height2
3 height3
...
89 height89
90 height90
打个比方,每个高度都小,低于2mm。
如何修改我的像素单位不失真函数以考虑制造商提供的毫米单位表,以获得最准确的未失真图像?