2011-02-07 121 views
0

如下因素片段是来自OpenCV的 find_obj.cpp这是使用SURF演示,OpenCV的SURF比较描述

 

double 
compareSURFDescriptors(const float* d1, const float* d2, double best, int length) 
{ 
    double total_cost = 0; 
    assert(length % 4 == 0); 
    int i; 
    for(i = 0; i best) 
      break; 
    } 
    return total_cost; 
} 

 

至于我可以告诉它检查欧氏距离,我不明白这是为什么它是以4人一组的方式进行的呢?为什么不一次计算整件事?

回答

3

通常情况下,这样做是为了使SSE优化成为可能。 SSE寄存器的长度是128位,可以包含4个浮点数,因此可以使用一条指令并行执行4个减法运算。

另一个好处:你必须检查循环计数器后,只有每第四个差异。即使编译器不使用机会来生成SSE代码,这也会使代码更快。例如,VS2008没有,甚至没有-O2:

  
     double t0 = d1[i] - d2[i]; 
00D91666 fld   dword ptr [edx-0Ch] 
00D91669 fsub  dword ptr [ecx-4] 
     double t1 = d1[i+1] - d2[i+1]; 
00D9166C fld   dword ptr [ebx+ecx] 
00D9166F fsub  dword ptr [ecx] 
     double t2 = d1[i+2] - d2[i+2]; 
00D91671 fld   dword ptr [edx-4] 
00D91674 fsub  dword ptr [ecx+4] 
     double t3 = d1[i+3] - d2[i+3]; 
00D91677 fld   dword ptr [edx] 
00D91679 fsub  dword ptr [ecx+8] 
     total_cost += t0*t0 + t1*t1 + t2*t2 + t3*t3; 
00D9167C fld   st(2) 
00D9167E fmulp  st(3),st 
00D91680 fld   st(3) 
00D91682 fmulp  st(4),st 
00D91684 fxch  st(2) 
00D91686 faddp  st(3),st 
00D91688 fmul  st(0),st 
00D9168A faddp  st(2),st 
00D9168C fmul  st(0),st 
00D9168E faddp  st(1),st 
00D91690 faddp  st(2),st 
1

我认为这是因为对于每个分区域我们都会得到4个数字。完全4x4x4子区域制作64个长度矢量。所以它基本上获得了2个子区域之间的差异。