鱼眼相机模型-MEI

参考文献: Single View Point Omnidirectional Camera Calibration from Planar Grids

  1. 相机模型如下:
cpp 复制代码
   // 相机坐标系下的点投影到畸变图像
   // 输入:相机坐标系点坐标cam  输出: 畸变图像素点坐标disPt
   void FisheyeCamAdapter::cam2DistImg(cv::Point3f &cam, cv::Point2f &disPt)
    {
        double r = cv::norm(cam);
        double dx_u = 0, dy_u = 0;
        if (r != 0)
        {
            cv::Point3f ps = cam / r;
            double x = ps.x / (ps.z + camInt.fXi);
            double y = ps.y / (ps.z + camInt.fXi);
            distortion(x, y, &dx_u, &dy_u);
            x += dx_u;
            y += dy_u;
            disPt.x = x * camInt.fGammaX + camInt.fCx;
            disPt.y = y * camInt.fGammaY + camInt.fCy;
        }
        else
        {
            disPt.x = camInt.fCx;
            disPt.y = camInt.fCy;
        }
    }
    // 无畸变图像到畸变图像
    void FisheyeCamAdapter::distortion(double mx_u, double my_u, double *dx_u, 
         double *dy_u)
    {
        double mx2_u = 0., my2_u = 0., mxy_u = 0., rho2_u = 0., rad_dist_u = 0.;

        double k1 = camInt.distortCoeff[0];
        double k2 = camInt.distortCoeff[1];
        double p1 = camInt.distortCoeff[2];
        double p2 = camInt.distortCoeff[3];
        double k5 = camInt.distortCoeff[4];

        mx2_u = mx_u * mx_u;
        my2_u = my_u * my_u;
        mxy_u = mx_u * my_u;
        rho2_u = mx2_u + my2_u;
        rad_dist_u = k1 * rho2_u + k2 * rho2_u * rho2_u + k5 * rho2_u * rho2_u * 
        rho2_u;
        *dx_u = mx_u * rad_dist_u + 2 * p1 * mxy_u + p2 * (rho2_u + 2 * mx2_u);
        *dy_u = my_u * rad_dist_u + 2 * p2 * mxy_u + p1 * (rho2_u + 2 * my2_u);
    }

反投影过程:畸变图中的像素坐标计算相机坐标系下坐标

cpp 复制代码
    cv::Point3f FisheyeCamAdapter::pointDis2Camera(const cv::Point2f &disPoint)
    {
        double mx_d, my_d, mx_u, my_u;
        double lambda;

        double xi = camInt.fXi;
        // Lift points to normalised plane
        float inv_K11 = 1 / camInt.fGammaX;
        float inv_K13 = -camInt.fCx / camInt.fGammaX;
        float inv_K22 = 1 / camInt.fGammaY;
        float inv_K23 = -camInt.fCy / camInt.fGammaY;
        mx_d = inv_K11 * (disPoint.x) + inv_K13;
        my_d = inv_K22 * (disPoint.y) + inv_K23;
        undistortGN(mx_d, my_d, &mx_u, &my_u, 100); // 去畸变坐标
        // Lift normalised points to the sphere (inv_hslash)
        cv::Point3f camera;
        if (xi == 1)
        {
            lambda = 2 / (mx_u * mx_u + my_u * my_u + 1);
            camera.x = lambda * mx_u;
            camera.y = lambda * my_u;
            camera.z = lambda - 1;
        }
        else
        {
            double sqrt_i = 1.0 + (1.0 - xi * xi) * (mx_u * mx_u + my_u * my_u);
            if (sqrt_i < 0)
            {
                camera.x = -1000000;
                camera.y = -1000000;
                camera.z = 1;
            }
            else
            {
                lambda = (xi + sqrt(sqrt_i)) / (1.0 + mx_u * mx_u + my_u * my_u);
                camera.x = lambda * mx_u;
                camera.y = lambda * my_u;
                camera.z = lambda - xi;
            }
        }
        return camera;
    }
相关推荐
小程故事多_802 小时前
OpenClaw工具引擎架构全解析,AI Agent的“双手”如何落地实操
人工智能·架构·aigc·ai编程·openclaw
qq_452396232 小时前
【AI 架构师】第十篇:Agent 工业化部署 —— 从 FastAPI 到云端全链路监控
网络·人工智能·ai·fastapi
前端摸鱼匠2 小时前
【AI大模型春招面试题11】什么是模型的“涌现能力”(Emergent Ability)?出现条件是什么?
人工智能·算法·ai·自然语言处理·面试·职场和发展
新缸中之脑2 小时前
如何合法地逆向SynthID
人工智能
剑穗挂着新流苏3123 小时前
115_PyTorch 实战:从零搭建 CIFAR-10 完整训练与测试流水线
人工智能·pytorch·深度学习·神经网络
Veggie263 小时前
【Java深度学习】PyTorch On Java 系列课程 第八章 17 :模型评估【AI Infra 3.0】[PyTorch Java 硕士研一课程]
java·人工智能·深度学习
链上杯子3 小时前
《2026 LangChain零基础入门:用AI应用框架快速搭建智能助手》第8课(完结篇):小项目实战 + 部署 —— 构建网页版个人知识库 AI 助手
人工智能·langchain
东方不败之鸭梨的测试笔记4 小时前
AI生成测试用例方案
人工智能·测试用例
笨手笨脚の4 小时前
AI 基础概念
人工智能·大模型·prompt·agent·tool
飞睿科技5 小时前
解析 ESP-AirPuff 泡芙一号的 ESP32-P4 大模型 AI 智能体方案
人工智能