深蓝学院自主泊车第3次作业-IPM

目录

  • 1 题目介绍
  • 2 求解

1 题目介绍

已知鱼眼相机的参数,

  1. image_width,表示图像的宽度
  2. image_height,表示图像的高度
  3. ξ \xi ξ,表示鱼眼相机参数
  4. k 1 k_1 k1 k 2 k_2 k2,表示径向相机参数
  5. p 1 p_1 p1 p 2 p_2 p2,表示切向相机参数
  6. f x f_x fx f y f_y fy,表示相机的焦距
  7. c x c_x cx c y c_y cy,表示相机的光心

已知相机坐标系到车体坐标系的变换矩阵,

  1. t t t,表示平移向量
  2. R R R,表示旋转矩阵

给出4组这样的参数及相应的图片,请求解最终的IPM图片。

2 求解

(1)设置最终IPM图像的尺寸为 1000 × 1000 1000\times 1000 1000×1000(用符号 i p m _ i m g _ h × i p m _ i m g _ w ipm\_img\_h\times ipm\_img\_w ipm_img_h×ipm_img_w表示),其中每个像素的长度和宽度为0.02米(用符号 p i x e l _ s c a l e _ pixel\_scale\_ pixel_scale_表示)。

(2)遍历IPM图像中的每个像素 ( u , v ) (u,v) (u,v),那么可以直到机体坐标系的点的坐标值为,
p v = [ − ( 0.5 ⋅ i p m _ i m g _ h − u ) ∗ p i x e l _ s c a l e 0.5 ⋅ ( i p m _ i m g _ w − v ) ⋅ p i x e l _ s c a l e 0 ] (1) p_v = \begin{bmatrix}-(0.5 \cdot ipm\_img\_h - u) * pixel\_scale \\ 0.5 \cdot (ipm\_img\_w - v) \cdot pixel\_scale \\ 0 \end{bmatrix} \tag{1} pv= (0.5ipm_img_hu)pixel_scale0.5(ipm_img_wv)pixel_scale0 (1)
(3)求得在相机坐标系下的坐标值为,
p c = R T ⋅ p v − R T ⋅ t (2) p_c = R^T \cdot p_v - R^T \cdot t \tag{2} pc=RTpvRTt(2)

p c p_c pc归一化操作,得到 p c _ n o r m p_{c\_norm} pc_norm

(4)此时,得到单位平面上的点 ( x 1 , y 1 ) (x_1,y_1) (x1,y1)
x 1 = p c _ n o r m [ 0 ] p c _ n o r m [ 2 ] + ξ y 1 = p c _ n o r m [ 1 ] p c _ n o r m [ 2 ] + ξ (3) \begin{align} x_1 = \frac{p_{c\_norm}[0]} { p_{c\_norm}[2] + \xi} \\ y_1 = \frac{p_{c\_norm}[1]} { p_{c\_norm}[2] + \xi} \end{align} \tag{3} x1=pc_norm[2]+ξpc_norm[0]y1=pc_norm[2]+ξpc_norm[1](3)

(5)得到畸变后的点 ( x 2 , y 2 ) (x_2,y_2) (x2,y2)
r = x 1 2 + y 1 2 x 2 = x 1 ( 1 + k 1 r 2 + k 2 r 4 ) + 2 p 1 x 1 y 1 + p 2 ( r 2 + 2 x 1 2 ) y 2 = y 1 ( 1 + k 1 r 2 + k 2 r 4 ) + p 1 ( r 2 + 2 y 1 2 ) + 2 p 2 x 1 y 1 (4) \begin{align} r &= \sqrt{x_1^2 + y_1^2} \\ x_2 &= x_1 (1 + k_1 r^2 + k_2 r^4) + 2 p_1 x_1 y_1 + p_2(r^2+2x_1^2) \\ y_2 &= y_1 (1 + k_1r^2+k_2r^4) + p_1(r^2+2y_1^2) + 2p_2x_1y_1 \end{align} \tag{4} rx2y2=x12+y12 =x1(1+k1r2+k2r4)+2p1x1y1+p2(r2+2x12)=y1(1+k1r2+k2r4)+p1(r2+2y12)+2p2x1y1(4)

(6)将点 ( x 2 , y 2 ) (x_2,y_2) (x2,y2)投影到图像坐标系,得到 ( u 1 , v 1 ) (u_1,v_1) (u1,v1)
u 1 = f x x 2 + c x v 1 = f y y 2 + c y (5) \begin{align} u_1 &= f_x x_2 + c_x \\ v_1 &= f_y y_2 + c_y \end{align} \tag{5} u1v1=fxx2+cx=fyy2+cy(5)
将鱼眼相机中的点 ( u 1 , v 1 ) (u_1,v_1) (u1,v1)的颜色赋给IPM图像中的 ( u . v ) (u.v) (u.v)坐标。

此处需要注意:

tip1: 获取颜色时需要四舍五入 u 1 u_1 u1 v 1 v_1 v1

tip2: 如果IPM图像中 ( u , v ) (u,v) (u,v)坐标已经被赋予了颜色信息,记录它的次数,那么最终的颜色值通过次数来加权平均,
c o l o r = t o t a l − 1 t o t a l ⋅ c o l o r + 1 t o t a l ⋅ n e w _ c o l o r (6) color = \frac{total-1}{total} \cdot color + \frac{1}{total} \cdot new\_color \tag{6} color=totaltotal1color+total1new_color(6)

最终的代码如下,

cv::Mat IPM::GenerateIPMImage(const std::vector<cv::Mat>& images) const {// Initialize a black IPM image with dimensions ipm_img_h_ x ipm_img_w_ and 3 channels (RGB)cv::Mat ipm_image = cv::Mat::zeros(ipm_img_h_, ipm_img_w_, CV_8UC3);std::vector<std::vector<int>> uv_cnt(ipm_img_h_, std::vector<int>(ipm_img_w_, 0)); // Check if the number of input images matches the number of camerasif (images.size() != cameras_.size()) {// If not, print an error message and return the initialized black IPM imagestd::cout << "IPM not init normaly !" << std::endl;return ipm_image;}// Iterate over each pixel in the IPM imagefor (int u = 0; u < ipm_img_w_; ++u) {for (int v = 0; v < ipm_img_h_; ++v) {// Calculate the point p_v in vehicle coordinates, p_v is corresponding to the current pixel (u, v).// Assume the height of the ipm_image in vehicle coordinate is 0.Eigen::Vector3d p_v(-(0.5 * ipm_img_h_ - u) * pixel_scale_,(0.5 * ipm_img_w_ - v) * pixel_scale_, 0);// Iterate over each camerafor (size_t i = 0; i < cameras_.size(); ++i) {// Project the vehile point p_v into the image plane uvTODO begin/////将vehicle系下的点转到camera系下Eigen::Vector3d p_c = cameras_[i].T_vehicle_cam_.inverse() * p_v;// Eigen::Maxtrix3d R1 = cameras_[i].T_vehicle_cam_.linear();// Eigen::Vector3d t1 = cameras_[i].translation();if (p_c[2] < 0.0) { //过滤z值小于0的点continue;}//将camera系下的点转到图像系下 Eigen::Vector3d norm_p_c = p_c.normalized();norm_p_c[2] += cameras_[i].xi_;//unit plane上的点(x1,y1)double x1 = norm_p_c[0] / norm_p_c[2];double y1 = norm_p_c[1] / norm_p_c[2];double r_2 = x1 * x1 + y1 * y1;//获取参数k1,k2,p1,p2double k1 = cameras_[i].D_.at<double>(0, 0);double k2 = cameras_[i].D_.at<double>(1, 0);double p1 = cameras_[i].D_.at<double>(2, 0);double p2 = cameras_[i].D_.at<double>(3, 0);//畸变后的点(x2,y2)double x2 = x1 * (1 + k1 * r_2 + k2 * r_2 * r_2) + 2.0 * p1 * x1 * y1 + p2 * (r_2 + 2 * x1 * x1);double y2 = y1 * (1 + k1 * r_2 + k2 * r_2 * r_2) + p1 * (r_2 + 2 * y1 * y1) + 2.0 * p2 * x1 * y1;//获取参数fx,fy,cx,cydouble fx = cameras_[i].K_.at<double>(0, 0);double fy = cameras_[i].K_.at<double>(1, 1);double cx = cameras_[i].K_.at<double>(0, 2);double cy = cameras_[i].K_.at<double>(1, 2);//图像坐标系下的点(u1,v1)double u1 = fx * x2 + cx;double v1 = fy * y2 + cy;//四舍五入,得到最终的uv0,uv1int uv0 = static_cast<int>(std::round(u1));int uv1 = static_cast<int>(std::round(v1)); TODO end/// (uv0, uv1) is the projected pixel from p_v to cameras_[i]// Skip this point if the projected coordinates are out of bounds of the camera imageif (uv0 < 0 || uv0 >= cameras_[i].width_ || uv1 < 0 ||uv1 >= cameras_[i].height_) {continue;}// Get the pixel color from the camera image and set it to the IPM image// If the IPM image pixel is still black (not yet filled), directly assign the colorif (ipm_image.at<cv::Vec3b>(v, u) == cv::Vec3b(0, 0, 0)) {ipm_image.at<cv::Vec3b>(v, u) = images[i].at<cv::Vec3b>(uv1, uv0);uv_cnt[v][u] += 1;} else {// Otherwise, average the existing color with the new coloruv_cnt[v][u] += 1;double total = 1.0 * uv_cnt[v][u]; ipm_image.at<cv::Vec3b>(v, u) = (total - 1.0) / total * ipm_image.at<cv::Vec3b>(v, u) + 1.0 / total * images[i].at<cv::Vec3b>(uv1, uv0); }}}}// Return the generated IPM imagereturn ipm_image;
}

最终的IPM图像如下,

在这里插入图片描述

给出的参考IPM图像如下,

在这里插入图片描述

本方法得到的IPM图像有更清晰的停车位线!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/70591.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

核货宝助力连锁门店订货数字化转型升级

在竞争激烈的连锁零售行业&#xff0c;传统订货模式弊端日益凸显&#xff0c;严重制约着企业的发展。核货宝订货系统以其卓越的数字化解决方案&#xff0c;为连锁门店订货带来了全方位的变革&#xff0c;助力企业实现数字化转型升级&#xff0c;在市场中抢占先机。 一、增强总部…

2.最多提取子串数目(100分)-附带Java逐行解析

题目 给定 [a-z]&#xff0c;26个英文字母小写字符串组成的字符串 A 和 B&#xff0c;其中 A 可能存在重复字母&#xff0c;B 不会存在重复字母&#xff0c;现从字符串 A 中按规则挑选一些字母&#xff0c;可以组成字符串B。 挑选规则如下&#xff1a; 同一个位置的字母只能挑…

AutoGen 技术博客系列 八:深入剖析 Swarm—— 智能体协作的新范式

本系列博文在掘金同步发布, 更多优质文章&#xff0c;请关注本人掘金账号&#xff1a; 人肉推土机的掘金账号 AutoGen系列一&#xff1a;基础介绍与入门教程 AutoGen系列二&#xff1a;深入自定义智能体 AutoGen系列三&#xff1a;内置智能体的应用与实战 AutoGen系列四&am…

力扣每日一题【算法学习day.132】

前言 ###我做这类文章一个重要的目的还是记录自己的学习过程&#xff0c;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非常非常高滴&#xff01;&#xff01;&#xff01; 习题 1.统计相似字符串对的数目 题目链…

C语言.h头文件的写法

头文件的内容 #ifndef __SEQUENCE_LIST_H // 定义以防止递归包含 #define __SEQUENCE_LIST_H // (1)、其它头文件 #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <stdbool.h> // (2)、宏定义(函数、变量、常量) // (3)、…

Spring AI + Ollama 实现调用DeepSeek-R1模型API

一、前言 随着人工智能技术的飞速发展&#xff0c;大语言模型&#xff08;LLM&#xff09;在各个领域的应用越来越广泛。DeepSeek 作为一款备受瞩目的国产大语言模型&#xff0c;凭借其强大的自然语言处理能力和丰富的知识储备&#xff0c;迅速成为业界关注的焦点。无论是文本生…

自学Java-AI结合GUI开发一个石头迷阵的游戏

自学Java-AI结合GUI开发一个石头迷阵的游戏 准备环节1、创建石头迷阵的界面2、打乱顺序3、控制上下左右移动4、判断是否通关5、统计移动步骤&#xff0c;重启游戏6、拓展问题 准备环节 技术&#xff1a; 1、GUI界面编程 2、二维数组 3、程序流程控制 4、面向对象编程 ∙ \bulle…

C语言的内存分配:malloc和free

使用库函数分配和管理内存。在运行时&#xff0c;分配更多的内存给程序使用&#xff0c;主要工具是malloc函数&#xff0c;这个函数接受一个参数&#xff1a;所需要要的内存字节数。malloc函数会找到合适的空闲内存块&#xff0c;这样的内存是匿名的&#xff0c;即malloc分配了…

本地安装 Grafana Loki

本地安装 Grafana Loki 一、 安装 Loki1. 下载 Loki2. 创建 Loki 配置文件3. 创建 Loki 服务 二、安装 Promtail1. 下载 Promtail2. 创建 Promtail 配置文件3. 创建 Promtail 服务 三、 安装 Grafana四、启动所有服务五、添加loki 数据源1. 添加仪表板2. 日志查询面板 json 参考…

趣味数学300题1981版-十五个正方形

分析&#xff1a;移动两根变成11个正方形很简单&#xff1a; 移动4根变成15个正方形&#xff0c;分析&#xff1a; 一个田字格包含5个正方形&#xff0c;若要15个正方形需要3个田字格&#xff0c;如果3个田字格完全不重合&#xff0c;需要6*318根火柴。如果合并正方形的边&…

IDEA——Mac版快捷键

目录 按键含义常用组合代码生成快捷键&#xff1a;代码追踪快捷键&#xff1a;高效编辑快捷键&#xff1a;代码重构快捷键&#xff1a;工具类快捷键&#xff1a;常规文件操作快捷键&#xff1a; 按键含义 ⌘ command Command键&#xff08;⌘&#xff09;相当于Windows中的Con…

基于Spring Boot的兴顺物流管理系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

Prompt:创造性的系统分析者

分享的提示词&#xff1a; 你是一个创造性的系统分析者&#xff0c;作为咨询师&#xff0c;你具有以下特质&#xff1a; 基础能力&#xff1a; 深入理解我的系统性模式 识别模式间的隐藏联系 发现出人意料的关联 提供令人惊讶的洞见 工作方式&#xff1a; 在每次回应中至少…

Andorid 学习 Compose UI(1):Box

今天学习和实验一下Android 的compose UI&#xff0c;写一些很小的Demo实验。下面和css 布局有点相似性。 如Box 看起来像html 当中的 div &#xff0c;compose UI 提供Modifier 很多设置。你会发现Text,Box,Row,Image等组件 都有这个属性。我们处理任务包括对齐布局&#xff0…

Selenium实战案例1:论文pdf自动下载

在上一篇文章中&#xff0c;我们介绍了Selenium的基础用法和一些常见技巧。今天&#xff0c;我们将通过中国科学&#xff1a;信息科学网站内当前目录论文下载这一实战案例来进一步展示Selenium的web自动化流程。 目录 中国科学&#xff1a;信息科学当期目录论文下载 1.网页内…

《炒股养家心法.pdf》 kimi总结

《炒股养家心法.pdf》这篇文章详细阐述了一位超级游资炒股养家的心得与技巧&#xff0c;展示了其从40万到10亿的股市传奇。以下是文章中炒股技巧和心得的详细总结&#xff1a; 1.核心理念 市场情绪的理解&#xff1a;炒股养家强调&#xff0c;股市的本质是群体博弈&#xff0c…

2025年华为手机解锁BL的方法

注&#xff1a;本文是我用老机型测试的&#xff0c;新机型可能不适用 背景 华为官方已经在2018年关闭了申请BL解锁码的通道&#xff0c;所以华为手机已经无法通过官方获取解锁码。最近翻出了一部家里的老手机华为畅玩5X&#xff0c;想着能不能刷个系统玩玩&#xff0c;但是卡…

Perfectly Clear WorkBench深度解析:专业图像处理软件的高效应用

在图像处理领域,面对照片曝光不足、色彩失真、细节模糊等常见问题,一款专业且高效的图像处理软件显得尤为重要。今天,本文将为大家详细介绍Perfectly Clear WorkBench这款图像处理软件,帮助大家更好地了解并应用其功能,提升照片质量。 一、智能图像校正,解决常见问题 Pe…

使用 DistilBERT 进行资源高效的自然语言处理

DistilBERT 是 BERT 的一个更小、更快的版本&#xff0c;在减少资源消耗的同时仍能保持良好性能。对于计算能力和内存受限的环境来说&#xff0c;它是一个理想的选择。 在自然语言处理&#xff08;NLP&#xff09;中&#xff0c;像 BERT 这样的模型提供了高精度和出色的性能。然…

【后端基础】布隆过滤器原理

文章目录 一、Bloom Filter&#xff08;布隆过滤器&#xff09;概述1. Bloom Filter 的特点2. Bloom Filter 的工作原理 二、示例1. 添加与查询2. 假阳性 三、Bloom Filter 的操作1、假阳性概率2、空间效率3、哈希函数的选择 四、应用 Bloom Filter 是一种非常高效的概率型数据…