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

逆透视变换详解 及 代码实现(一) 中主要是原理的说明:


一、世界坐标轴和摄像机坐标轴

从下图中可以看到,世界坐标为(X,Y,Z)  相机坐标为(Xc,Yc,Zc)

而世界坐标变换到相机坐标存在一个旋转矩阵变换R以及一个位移变换T。



根据上图可以得到世界坐标到相机坐标的公式变换!!

                       世界坐标到相机坐标的公式


如果假设没有坐标的平移存在即t在这里不起作用,可以简化公式为:



接下来我们来说下不同坐标轴变换的旋转矩阵

从二维图像入手,坐标变换如下图所示

如果假设不存在位移变换,那么x0 和y0 将变为0。


现在从二维图像变到三维图像上的变换,假设固定一个(X,Y,Z)轴 旋转其他两个轴组成的平面。

1、绕X轴旋转 theta 

                                

2、绕Y轴旋转

                             

3、绕Z轴旋转

                              

-------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------------

下面为相机坐标和平面坐标系(成像投影关系)


根据上述的关系我们可以推得:

      

    矩阵形式为:  

  


---------------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------------

3、从平面坐标得到的我们看到的(照片)图像坐标系

数字图像在计算机内为MXN数组,M行N列的图像中每一个元素(pixel)数值就是图像点的亮度(灰度)。

如图,在图像上定义直角坐标系U,V,每一个像素为单位的图像坐标系坐标,

由于(u,v)只能表示像素位于数组中的列数与行数,并没有使用物理单位表示该像素在图像中位置,

所以需要再建立以物理单位(mm)表示的图像坐标系,该图像坐标系以图像内某一点uv(0,0)为原点,x轴和y轴分别平行于u、v。



如图中,(u、v)表示以像素为单位的图像坐标系的坐标,(X、Y)表示以mm为单位的图像坐标系的坐标。

假设每一个像素在X轴与Y轴方向上的物理尺寸为dx、dy,则图像任意一个像素在两个坐标系下的坐标有如下关系,

 其中(u0 ,v0) = xy(0,0)

进而得到如下的矩阵表达:


---------------------------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------------------------

到此 逆透视变换就全部完成了!!!!


下面要说下 逆透视变换需要注意的问题,   因为有消失点的存在,也就是说当我们看火车轨道的时候总在某个距离上看到两条轨道重合到一起后消失。

对于空间中任一点(XW,YW,ZWT,投影之后的对应像点为(u,v,1)T,写成矩阵形式:


其中AR为变换矩阵,假设M = AR


将矩阵展开,这里去Zc = 1 可以得到如下关系式。



消失点可以认为是空间直线上无穷远处的点投影在图像上所成的像点。对于空间中某一直线L,方向为(dx,dy,dz),给定直线上坐标(ax,ay,az),所以直线上任一点A可以表示为:



 

当趋于无穷时可以得到



从而得到消失点的坐标。


注:逆透视变换的范围不能到达消失点,否则不能还原。


整体变换的示意图:


逆透视变换详解 及 代码实现(二)

根据上述原理,结合应用场景,列出代码的实现!!



  • 48
    点赞
  • 337
    收藏
    觉得还不错? 一键收藏
  • 33
    评论
Java动态代理是一种通过在运行时期间生成代理对象来实现对目标对象进行代理的技术。它可以在不修改目标对象的情况下,为目标对象提供额外的功能。 Java动态代理实现的核心是利用了Java的反射机制和动态生成类的技术。在动态代理中,我们需要定义一个代理类和一个实现了InvocationHandler接口的处理器类。 代理类是在运行时动态生成的类,它是目标对象的代理,它实现了与目标对象相同的接口,并且在方法调用时会通过InvocationHandler接口的实现类来处理方法的调用。InvocationHandler接口中只有一个方法invoke(Object proxy, Method method, Object[] args),这个方法就是用来处理方法调用的。 下面是一个简单的Java动态代理的示例代码: ``` import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynamicProxy implements InvocationHandler { private Object target; public DynamicProxy(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before method"); Object result = method.invoke(target, args); System.out.println("after method"); return result; } public static void main(String[] args) { RealObject realObject = new RealObject(); DynamicProxy dynamicProxy = new DynamicProxy(realObject); Interface proxyObject = (Interface) Proxy.newProxyInstance( Interface.class.getClassLoader(), new Class[] { Interface.class }, dynamicProxy); proxyObject.doSomething(); } } interface Interface { void doSomething(); } class RealObject implements Interface { public void doSomething() { System.out.println("RealObject doSomething"); } } ``` 在这个示例中,我们定义了一个DynamicProxy类作为代理处理器,它实现了InvocationHandler接口。在DynamicProxy类中,我们定义了一个Object类型的target属性,它表示目标对象。 在DynamicProxy类的invoke方法中,我们先输出了一句话“before method”,然后通过反射机制调用目标对象的方法,最后输出了一句话“after method”。 在DynamicProxy类的main方法中,我们首先创建了一个RealObject对象作为目标对象,然后创建了一个DynamicProxy对象,并将RealObject对象作为参数传递给DynamicProxy对象的构造方法。接着,我们通过Proxy.newProxyInstance方法动态生成了一个代理对象,并将DynamicProxy对象作为参数传递给它。最后,我们调用代理对象的doSomething方法。 当我们运行这个程序时,它会输出以下内容: ``` before method RealObject doSomething after method ``` 这表明,在代理对象调用doSomething方法时,它会先调用DynamicProxy类的invoke方法,在invoke方法中,我们将先输出一句话“before method”,然后调用目标对象的方法,最后输出一句话“after method”。 Java动态代理的优点是可以在运行时期间动态生成代理对象,不需要预先定义代理类,这样可以大大减少代码量。同时,Java动态代理也具有很好的灵活性,可以对不同的目标对象生成不同的代理对象,实现不同的处理逻辑。
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值