根据 逆透视变换详解 及 代码实现(一)的原理

下面我用车上拍摄的车道图像,采用逆透视变换得到的图像,给出代码前我们先看下处理结果。

首先是原始图像:

下图为逆透视变换图像:

下面说具体的实现吧!!

一、参数设置:

1、需要知道相机的内部参数(这个具体步骤可以找相关文档,这里就不具体展开说)。

我们这里假设已经获取内部参数:

相机焦距,相机光学中心, 相机高度, 相机的俯仰角, 相机的偏航角, 相机拍摄出的图像尺寸。

参数说明:  其中偏航角俯仰角 就是在(一)中所说的世界坐标经过旋转矩阵得到相应的相机坐标。  而偏航角和俯仰角将决定这个旋转矩阵。  而相机焦距  和相机光学中心 是可以从相机标定后得出 ,相机高度需要自己测量。

图像尺寸,是拍出图像的尺寸。

2、 设定逆透视变换的参数:

逆透视图像的尺寸,需要进行逆透视变换的区域,逆透视变换的差值算法。

逆透视变换的区域:原始图像中需要变换的区域(当然这个区域不能超过消失点区域,后面会说到)

逆透视图像的尺寸: 就是需要将逆透视变换区域映射到这个逆透视图像上。

差值算法:因为需要映射,所以某些数值需要估计出,这里用双线性差值。

二、

根据相机的内部参数计算消失点:

因为图像是二维的,所以消失点是是一个二维坐标。

code:

function [ vp ] = GetVanishingPoint( cameraInfo )
%GetVanishingPoint Summary of this function goes here
%   Detailed explanation goes herevpp = [ sin(cameraInfo.yaw*pi/180)/cos(cameraInfo.pitch*pi/180);cos(cameraInfo.yaw*pi/180)/cos(cameraInfo.pitch*pi/180);0];tyawp = [cos(cameraInfo.yaw*pi/180), -sin(cameraInfo.yaw*pi/180), 0;         sin(cameraInfo.yaw*pi/180), cos(cameraInfo.yaw*pi/180), 0;0, 0, 1];tpitchp = [1, 0, 0;0, -sin(cameraInfo.pitch*pi/180), -cos(cameraInfo.pitch*pi/180);0, cos(cameraInfo.pitch*pi/180), -sin(cameraInfo.pitch*pi/180)];transform = tyawp*tpitchp;t1p = [cameraInfo.focalLengthX, 0, cameraInfo.opticalCenterX;0, cameraInfo.focalLengthY, cameraInfo.opticalCenterY;0, 0, 1];
transform = t1p*transform;vp = transform*vpp;end

三、利用消失点可以得到uv平面中的图像范围和对应的xy平面的范围

code:

uvLimitsp = [ vp.x,         ipmInfo.ipmRight, ipmInfo.ipmLeft,  vp.x;ipmInfo.ipmTop, ipmInfo.ipmTop, ipmInfo.ipmTop,   ipmInfo.ipmBottom];xyLimits = TransformImage2Ground(uvLimitsp,cameraInfo);
function [ xyLimits ] = TransformImage2Ground( uvLimits,cameraInfo )
%TransformImage2Ground Summary of this function goes here
%   Detailed explanation goes here
[row , col ] = size(uvLimits);
inPoints4 = zeros(row+2,col);
inPoints4(1:2,:) = uvLimits;
inPoints4(3,:) = 1;
inPoints3 = inPoints4(1:3,:);c1 = cos(cameraInfo.pitch*pi/180);
s1 = sin(cameraInfo.pitch*pi/180);
c2 = cos(cameraInfo.yaw*pi/180);
s2 = sin(cameraInfo.yaw*pi/180);matp= [-cameraInfo.cameraHeight*c2/cameraInfo.focalLengthX,cameraInfo.cameraHeight*s1*s2/cameraInfo.focalLengthY,(cameraInfo.cameraHeight*c2*cameraInfo.opticalCenterX/cameraInfo.focalLengthX)- (cameraInfo.cameraHeight *s1*s2* cameraInfo.opticalCenterY/ cameraInfo.focalLengthY) - cameraInfo.cameraHeight *c1*s2;cameraInfo.cameraHeight *s2/cameraInfo.focalLengthX, ...cameraInfo.cameraHeight *s1*c2/cameraInfo.focalLengthY, ...(-cameraInfo.cameraHeight *s2* cameraInfo.opticalCenterX ..../cameraInfo.focalLengthX)-(cameraInfo.cameraHeight *s1*c2* ....cameraInfo.opticalCenterY /cameraInfo.focalLengthY) -  ...cameraInfo.cameraHeight *c1*c2;0, cameraInfo.cameraHeight *c1/cameraInfo.focalLengthY, (-cameraInfo.cameraHeight *c1* cameraInfo.opticalCenterY/cameraInfo.focalLengthY)+cameraInfo.cameraHeight*s1;0, -c1 /cameraInfo.focalLengthY,(c1* cameraInfo.opticalCenterY /cameraInfo.focalLengthY) - s1];inPoints4 = matp*inPoints3;
inPointsr4 = inPoints4(4,:);
div = inPointsr4;
inPoints4(1,:) = inPoints4(1,:)./div;
inPoints4(2,:) = inPoints4(2,:)./div;
inPoints2 = inPoints4(1:2,:);
xyLimits = inPoints2;end

四、根据得到的范围计算xy平面的一一对应的映射

row1 = xyLimits(1,:);
row2 = xyLimits(2,:);
xfMin = min(row1); xfMax = max(row1);
yfMin = min(row2); yfMax = max(row2);[outRow outCol] = size(outImage);
stepRow = (yfMax - yfMin)/outRow;
stepCol = (xfMax - xfMin)/outCol;
xyGrid = zeros(2,outRow*outCol);
y = yfMax-0.5*stepRow;for i = 1:outRowx = xfMin+0.5*stepCol;for j = 1:outColxyGrid(1,(i-1)*outCol+j) = x;xyGrid(2,(i-1)*outCol+j) = y;x = x + stepCol;endy = y - stepRow;
end

五、将xy平面的映射转换到uv平面,并画出这个映射

%TransformGround2Image
uvGrid = TransformGround2Image(xyGrid,cameraInfo);
% Image mean
means = mean(R(:))/255;
RR = double(R)/255;
for i=1:outRowfor j = 1:outCol;ui = uvGrid(1,(i-1)*outCol+j);vi = uvGrid(2,(i-1)*outCol+j);if (ui<ipmInfo.ipmLeft || ui>ipmInfo.ipmRight || vi<ipmInfo.ipmTop || vi>ipmInfo.ipmBottom) outImage(i,j) = means;elsex1 = int32(ui); x2 = int32(ui+1);y1 = int32(vi); y2 = int32(vi+1);x = ui-double(x1) ;  y = vi-double(y1);val = double(RR(y1,x1))*(1-x)*(1-y)+double(RR(y1,x2))*x*(1-y)+double(RR(y2,x1))*(1-x)*y+double(RR(y2,x2))*x*y;outImage(i,j) = val;endend
end

最终可以显示这个图像:如上面的逆透视变化图像!

具体的code,可以在这里下载。如果问题可以留言交流!!

##修改时间2019-01-23##begin##

鉴于目前csdn下载积分需求比较高,我把代码挂在github上

https://github.com/yeyang1021/matlab_IPM

##修改时间2019-01-23##end##

另外,如果需要标定相机的可以参考这篇博文:

http://blog.csdn.net/yeyang911/article/details/52382722

逆透视变换详解 及 代码实现(二)相关推荐

  1. 逆透视变换详解 及 代码实现(一)

    逆透视变换详解 及 代码实现(一) 中主要是原理的说明: 一.世界坐标轴和摄像机坐标轴 从下图中可以看到,世界坐标为(X,Y,Z)  相机坐标为(Xc,Yc,Zc) 而世界坐标变换到相机坐标存在一个旋 ...

  2. 逆透视变换详解 及 代码实现

    逆透视变换详解 及 代码实现(一) 中主要是原理的说明: 一.世界坐标轴和摄像机坐标轴 从下图中可以看到,世界坐标为(X,Y,Z)  相机坐标为(Xc,Yc,Zc) 而世界坐标变换到相机坐标存在一个旋 ...

  3. 【运筹优化】凸多面体重叠判断算法:GJK 算法详解 C++代码实现二维情形的凸多边形重叠判断

    文章目录 一.GJK 算法简介 二.前置知识 2.1 二维向量的点乘和叉乘 2.2 三维向量叉乘 2.3 凸多边形 2.4 闵可夫斯基差 2.5 单纯形 2.6 Support 函数 三.GJK 算法 ...

  4. 水平集详解与代码分析二

    上一节我们分析了CV模型的原理并列出了演化公式,这一节我们将通过该公式编写CV模型的C++代码,代码调用了opencv库的一些函数,可以根据自己使用的版本更改.代码一一对应公式里的各项系数. 头文件. ...

  5. 数学建模——一维、二维插值模型详解Python代码

    数学建模--一维.二维插值模型详解Python代码 一.一维插值 # -*-coding:utf-8 -*- import numpy as np from scipy import interpol ...

  6. 一文速学数模-时序预测模型(四)二次指数平滑法和三次指数平滑法详解+Python代码实现

    目录 前言 二次指数平滑法(Holt's linear trend method) 1.定义 2.公式 二次指数平滑值: 二次指数平滑数学模型: 3.案例实现 三次指数平滑法(Holt-Winters ...

  7. 三维空间刚体运动1:旋转矩阵与变换矩阵(详解加代码示例)

    三维空间刚体运动1:旋转矩阵与变换矩阵(详解加代码示例) 1. 点.向量和坐标系 2.坐标系间的欧式变换 2.1 旋转 2.2 平移 3.齐次坐标和变换矩阵 4. 相似.仿射和射影变换 4.1 相似变 ...

  8. 支付接口教程,详解支付宝接口(二)

    支付宝的接口向来集成过程都让人觉得比较舒服,只有APP支付相对复杂,但也只是配置上复杂一些,只要清楚原理相信也不是什么难事.下面是以前介绍双钥加密原理的传送门: 支付接口教程特别篇,公钥与私钥,双钥加 ...

  9. TOPSIS(逼近理想解)算法原理详解与代码实现

    写在前面: 个人理解:针对存在多项指标,多个方案的方案评价分析方法,也就是根据已存在的一份数据,判断数据中各个方案的优劣.中心思想是首先确定各项指标的最优理想值(正理想值)和最劣理想值(负理想解),所 ...

最新文章

  1. 克里斯坦森的破坏性创新—《可以量化的管理学》
  2. AnyProxy代理
  3. 合并报表编制采用的理论_合并报表操作的整体思路梳理
  4. 祝师傅新婚快乐 :-)
  5. C语言家谱管理程序,课内资源 - 基于C语言实现的家谱管理系统
  6. 虚拟空间,域名解析,A记录,MX记录,CNAME记录,TTL 等 更多Web服务器相关名词解释
  7. 同步服务器客户端位置,服务器和客户端信息同步方式
  8. X-NUCA全国高校网安联赛7月训练题解
  9. 使用Regex.Replace()进行字符串的替换
  10. CPDA|数据分析师成长之路如何起步?
  11. 现代雷达系统分析与设计---数字中频正交采样
  12. iis 缓存 静态文件_强制更新IIS中的缓存JavaScript文件
  13. Lpl and Energy-saving Lamps 计蒜客多校
  14. 2019最新android实例开发视频教程
  15. linux centos7 镜像下载
  16. ppi 在线计算机,在线像素密度厘米英寸转换器(PPI)_三贝计算网_23bei.com
  17. linux eval命令详解,linux命令详解——eval
  18. 关于6pm.com海淘信用卡被要求银行授权码的问题
  19. html制作开心餐厅,二次元少女开心餐厅
  20. 中标麒麟操作系统设置或修改root密码

热门文章

  1. 工作所用的模块回滚脚本
  2. 转:Delphi2010新发现-类的构造和析构函数功能
  3. [小记]Centos7网络配置DNS配置解决、yum出错解决。
  4. mysql悲观锁总结和实践
  5. ExtJS和AngularJS比较
  6. django post and get?
  7. python实现链表的删除_Python中 为我们提供了一些独特的解决方案的方法特性
  8. Mybatis源码阅读(五 ):接口层——SqlSession
  9. Spring中BeanFactory和FactoryBean的区别
  10. html5链接mvc,LinkExtensions.ActionLink 方法 (System.Web.Mvc.Html) | Microsoft Docs