I discovered how to map a linear lens ,从destination坐标到source坐标。

如何计算从中心到鱼眼到直线的径向距离?

  • 1)。 我实际上很努力地将其反转,并将源坐标映射到目标坐标。按照我发布的转换函数的样式,代码的反函数是什么?
  • 2)。 我也看到我的失真在某些镜头上是不完美的-大概是那些不是严格线性的镜头。这些镜头的等效于源坐标和目标坐标是什么?同样,请提供更多的代码,而不仅仅是数学公式...




  • 我有一些要点描述了用鱼眼镜头拍摄的照片中的位置。

    我想将这些点转换为直线坐标。我想使图像不失真。

    我已经找到this description关于如何产生鱼眼效果,但是没有扭转它的方法。

    还有一个blog post描述如何使用工具来完成它。这些图片来自:

    (1):SOURCE Original photo link

    输入:修正了鱼眼失真的原始图像。

    (2):DESTINATION Original photo link

    输出:校正后的图像(技术上也可以使用透视校正,但这是一个单独的步骤)。

    您如何计算从中心到鱼眼到直线的径向距离?

    我的函数存根看起来像这样:
    Point correct_fisheye(const Point& p,const Size& img) {
        // to polar
        const Point centre = {img.width/2,img.height/2};
        const Point rel = {p.x-centre.x,p.y-centre.y};
        const double theta = atan2(rel.y,rel.x);
        double R = sqrt((rel.x*rel.x)+(rel.y*rel.y));
        // fisheye undistortion in here please
        //... change R ...
        // back to rectangular
        const Point ret = Point(centre.x+R*cos(theta),centre.y+R*sin(theta));
        fprintf(stderr,"(%d,%d) in (%d,%d) = %f,%f = (%d,%d)\n",p.x,p.y,img.width,img.height,theta,R,ret.x,ret.y);
        return ret;
    }
    

    或者,我可以在找到点之前以某种方式将图像从鱼眼转换为直线,但是我完全被OpenCV documentation所迷惑。在OpenCV中是否有一种简单的方法可以做到这一点,并且它的性能足以将其用于实时视频供稿?

    最佳答案

    description you mention指出针孔相机的投影(不引起镜头失真的投影)是通过以下方式建模的:

    R_u = f*tan(theta)
    

    普通鱼眼镜头相机的投影(即变形)的模型为
    R_d = 2*f*sin(theta/2)
    

    您已经知道R_d和theta,并且如果您知道相机的焦距(用f表示),那么校正图像就等于根据R_d和theta计算R_u。换一种说法,
    R_u = f*tan(2*asin(R_d/(2*f)))
    

    是您要寻找的公式。估计焦距f可以通过校准相机或其他方式来解决,例如让用户提供有关图像校正程度的反馈或使用原始场景的知识。

    为了使用OpenCV解决相同的问题,您必须获得相机的固有参数和镜头畸变系数。例如,参见Learning OpenCV的第11章(不要忘记检查correction)。然后,您可以使用诸如此类的程序(使用针对OpenCV的Python绑定(bind)编写)来消除镜头失真:
    #!/usr/bin/python
    
    # ./undistort 0_0000.jpg 1367.451167 1367.451167 0 0 -0.246065 0.193617 -0.002004 -0.002056
    
    import sys
    import cv
    
    def main(argv):
        if len(argv) < 10:
        print 'Usage: %s input-file fx fy cx cy k1 k2 p1 p2 output-file' % argv[0]
        sys.exit(-1)
    
        src = argv[1]
        fx, fy, cx, cy, k1, k2, p1, p2, output = argv[2:]
    
        intrinsics = cv.CreateMat(3, 3, cv.CV_64FC1)
        cv.Zero(intrinsics)
        intrinsics[0, 0] = float(fx)
        intrinsics[1, 1] = float(fy)
        intrinsics[2, 2] = 1.0
        intrinsics[0, 2] = float(cx)
        intrinsics[1, 2] = float(cy)
    
        dist_coeffs = cv.CreateMat(1, 4, cv.CV_64FC1)
        cv.Zero(dist_coeffs)
        dist_coeffs[0, 0] = float(k1)
        dist_coeffs[0, 1] = float(k2)
        dist_coeffs[0, 2] = float(p1)
        dist_coeffs[0, 3] = float(p2)
    
        src = cv.LoadImage(src)
        dst = cv.CreateImage(cv.GetSize(src), src.depth, src.nChannels)
        mapx = cv.CreateImage(cv.GetSize(src), cv.IPL_DEPTH_32F, 1)
        mapy = cv.CreateImage(cv.GetSize(src), cv.IPL_DEPTH_32F, 1)
        cv.InitUndistortMap(intrinsics, dist_coeffs, mapx, mapy)
        cv.Remap(src, dst, mapx, mapy, cv.CV_INTER_LINEAR + cv.CV_WARP_FILL_OUTLIERS,  cv.ScalarAll(0))
        # cv.Undistort2(src, dst, intrinsics, dist_coeffs)
    
        cv.SaveImage(output, dst)
    
    
    if __name__ == '__main__':
        main(sys.argv)
    

    还要注意,OpenCV使用的镜头畸变模型与您链接到的网页中的模型完全不同。

    关于math - 以编程方式校正鱼眼失真,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2477774/

    10-09 00:37