Stitching模块中focalsFromHomography初步研究

在Stitching模块中,通过“光束法平差”的时候,有一个步骤为“通过单应矩阵估算摄像头焦距”,调用的地方为:

void focalsFromHomography(const Mat& H, double &f0, double &f1, bool &f0_ok, bool &f1_ok)
{
    CV_Assert(H.type() == CV_64F && H.size() == Size(3, 3));
    const double* h = H.ptr<double>();
    double d1, d2; // Denominators
    double v1, v2; // Focal squares value candidates
    f1_ok = true;
    d1 = h[6] * h[7];
    d2 = (h[7] - h[6]) * (h[7] + h[6]);
    v1 = -(h[0] * h[1] + h[3] * h[4]) / d1;
    v2 = (h[0] * h[0] + h[3] * h[3] - h[1] * h[1] - h[4] * h[4]) / d2;
    if (v1 < v2) std::swap(v1, v2);
    if (v1 > 0 && v2 > 0) f1 = std::sqrt(std::abs(d1) > std::abs(d2) ? v1 : v2);
    else if (v1 > 0) f1 = std::sqrt(v1);
    else f1_ok = false;
    f0_ok = true;
    d1 = h[0] * h[3] + h[1] * h[4];
    d2 = h[0] * h[0] + h[1] * h[1] - h[3] * h[3] - h[4] * h[4];
    v1 = -h[2] * h[5] / d1;
    v2 = (h[5] * h[5] - h[2] * h[2]) / d2;
    if (v1 < v2) std::swap(v1, v2);
    if (v1 > 0 && v2 > 0) f0 = std::sqrt(std::abs(d1) > std::abs(d2) ? v1 : v2);
    else if (v1 > 0) f0 = std::sqrt(v1);
    else f0_ok = false;
}

本文具体分析focalsFromHomography,函数的参数定义:

Tries to estimate focal lengths from the given homography  
     under the assumption that the camera undergoes rotations around its centre only.    
     Parameters  
     H – Homography.  
     f0 – Estimated focal length along X axis.  
     f1 – Estimated focal length along Y axis.  
     f0_ok – True, if f0 was estimated successfully, false otherwise.  
     f1_ok – True, if f1 was estimated successfully, false otherwise.

可以看到它通过输入的单应矩阵,最后得到了相机焦距的估计值,计算的过程也比较复杂。那这样做的理由是什么了?具体计算的时候又是如何实现的了?

论文也就是算法的依据为《Construction of Panoramic Image Mosaics with Global and Local Alignment 》, Heung-Yeung Shum ([email protected]) and Richard Szeliski ([email protected])  page 17.method "focals from homgraphy matrix"

我将具体的内容截出来:

原论文中40-44的推导,分为两个部分。一个部分是从“8参数”的变换,得出和x轴,y轴两个方向焦距的关系;一个部分是通过行列式的数学性质,计算出两个方向的焦距。这两个部分我目前都没有掌握足够的资料来进行证明,如果有能够证明的同学麻烦联系我一下。

然后来看算法实现。如果认为论文的表述是正确的,那么依据数学函数来对比c++的实现

代码中的h0-h8直接对应论文中的m0-m8,仅以f0来观察,那么f0^2可能有两种取值(这里x^2 是 x * x的一种简单表示方法,代表阶乘)

f0^2 = - m2*m5/(m0*m3+m1*m4)或f0^2 = m5^2 - m2^2 /(m0^2 + m1^2 - m3^2 - m4 ^2)

看代码

d1 = h[0] * h[3] + h[1] * h[4];
那么
 v1 = -h[2] * h[5] / d1 =  -h[2] * h[5] /(h[0] * h[3] + h[1] * h[4])

d2 = h[0] * h[0] + h[1] * h[1] - h[3] * h[3] - h[4] * h[4];

 v2 = (h[5] * h[5] - h[2] * h[2]) / d2 = (h[5] * h[5] - h[2] * h[2]) / (h[0] * h[0] + h[1] * h[1] - h[3] * h[3] - h[4] * h[4])

前后是一一对应的,计算f0^2的两个值是没有问题的。但是这里f0有两个计算结果,最后选择哪个了?这一点在论文中没有说,在代码中采用的方法是首先判断v1,v2的符号,如果都是负数,那么肯定是计算错误了,因为它们所代表的f0^2肯定是非负数;然后判断v1,v2的大小,取其中比较大的那个来进行计算。

但是在

if (v1 > 0 && v2 > 0) f0 = std::sqrt(std::abs(d1) > std::abs(d2) ? v1 : v2);

我认为这样写是没有用的,我也在尝试联系一下相关对这个问题比较熟悉的人共同讨论。f1的计算方法是同样的。到这里已经得到f0和f1,分别对应x轴和y轴,为了得到最后的结果,那么会取

f = sqrt(f0 * f1)

则得到这个当应矩阵的对于焦距的估计值。那么focalsFromHomography的一次运算也就结束了。

时间: 2024-10-14 13:14:48

Stitching模块中focalsFromHomography初步研究的相关文章

《大数据分析中的计算智能研究现状与发展》—— 读后感

<大数据分析中的计算智能研究现状与发展>这篇文章是郭平.王可.罗阿理.薛明志发于2015年11月发表于软件学报. 该篇文章讨论了大数据分析中计算智能研究存在的问题和进一步的研究方向,阐述了数据源共享问题,并建议利用以天文学为代表的数据密集型基础科研领域的数据开展大数据分析研究.  大数据和人工智能是现代计算机技术应用的重要分支,近年来这两个领域的研究相互交叉促进,产生了很多新的方法.应用和价值.大数据和人工智能具有天然的联系,大数据的发展本身使用了许多人工智能的理论和方法,人工智能也因大数据技

iOS多线程的初步研究(一)-- NSThread

iOS多线程的初步研究(一)-- NSThread 对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NSThread.一般构造NSThread的线程对象可通过两种方式: 1. 初始化线程主方法: [NSThread detachNewThreadSelector:@selector(run:) toTarget:target withObject:obj];//类方法 或 NST

移动应用是大势所趋,微信开发初步研究尝试

微信在我们生活中已无所不在,几乎人手一个手机一个微信,天天刷朋友圈.而作为商家和企业应用的服务号和企业号的开发也是移动应用开发的一个新方向. 经过近期对微信开发进行初步研究,对微信开发有了一些了解,可以打通微信与数据库的查询及交互,实现一些应用系统的定制开发.接下来要做的就是根据实际业务需要来开工建设. 微信除了企业内部应用外,在商业环境的应用如支付.活动现场等的应用也是支持的较好.另外微信wifi项目也可作为一个独立分支结合无线路由器来作为一个广大的商业市场进行运作开发. 微信提供了工具和平台

iOS多线程的初步研究(四)-- NSTimer

 iOS多线程的初步研究(四)-- NSTimer 原文地址  http://www.cnblogs.com/sunfrog/p/3243230.html 理解run loop后,才能彻底理解NSTimer的实现原理,也就是说NSTimer实际上依赖run loop实现的. 先看看NSTimer的两个常用方法: + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelec

iOS多线程的初步研究(十)-- dispatch同步

GCD提供两种方式支持dispatch队列同步,即dispatch组和信号量. 一.dispatch组(dispatch group) 1. 创建dispatch组 dispatch_group_t group = dispatch_group_create(); 2. 启动dispatch队列中的block关联到group中 dispatch_group_async(group, queue, ^{ // ... }); 3. 等待group关联的block执行完毕,也可以设置超时参数 dis

移动应用是大势所趋,微信开发初步研究尝试(图文)

微信在我们生活中已无所不在,差点儿人手一个手机一个微信,天天刷朋友圈.而作为商家和企业应用的服务号和企业号的开发也是移动应用开发的一个新方向. 经过最近对微信开发进行初步研究.对微信开发有了一些了解,能够打通微信与数据库的查询及交互,实现一些应用系统的定制开发.接下来要做的就是依据实际业务须要来开工建设. 微信除了企业内部应用外,在商业环境的应用如支付.活动现场等的应用也是支持的较好.另外微信wifi项目也可作为一个独立分支结合无线路由器来作为一个广大的商业市场进行运作开发. 微信提供了工具和平

urllib模块中的方法

urllib模块中的方法 1.urllib.urlopen(url[,data[,proxies]]) 打开一个url的方法,返回一个文件对象,然后可以进行类似文件对象的操作.本例试着打开google >>> import urllib >>> f = urllib.urlopen('http://www.google.com.hk/') >>> firstLine = f.readline()   #读取html页面的第一行 >>>

Python 3.X 调用多线程C模块,并在C模块中回调python函数的示例

由于最近在做一个C++面向Python的API封装项目,因此需要用到C扩展Python的相关知识.在此进行简要的总结. 此篇示例分为三部分.第一部分展示了如何用C在Windows中进行多线程编程:第二部分将第一部分的示例进行扩展,展示了如何在python中调用多线程的C模块:第三部分扩展了第二部分,增加了在C模块的线程中回调python的演示. 本文所用的环境为:64位Win7 + python 3.4 x86 + vs2010 一.windows下的C语言多线程程序 windows下多线程编程

Python学习心得(三)函数之任意数量实参、任意数量关键字实参、导入模块中的函数

#!/usr/bin/python # -*- coding:utf-8 -*- ''' 1.传递任意数量的实参 Python允许函数传入任意数量的实参,例如: *messages形参名中的*表示让Python创建一个空的名称为messages的元组,接收传入的所有值 ''' def get_person_message(*messages): concat = '' for message in messages: concat += ' ' + message print "\nShow P