Kanade-Lucas-Tomasi Feature Tracker 代码分析

转自 : http://blog.csdn.net/dreamd1987/article/details/7907437

因为研究需要,仔细看了下代码,看看有什么可以利用的地方。

整体来说Kanade-Lucas-Tomasi Feature Tracker的方法就是首先找去特征点,之后用光流去跟踪的方法。

OpenCV中已经有了example,大家可以运行下看效果,同时Homepage:http://www.ces.clemson.edu/~stb/klt/

上有源码,整个的流程跟Opencv差不多。

我们以官网上的原程序中的example1进行分析:(剩下的几个例子整体流程都差不多,仅仅是目的不一样)

首先都是建立两个结构体:

[html]  view plain  copy
  1. tc = KLTCreateTrackingContext();  
  2. KLTPrintTrackingContext(tc);  
  3. fl = KLTCreateFeatureList(nFeatures);  

tc就是跟踪的中用到的一些参数在选特征点的时候也有用到。

fl就是我们说道德特征点了,包括了特征值和特征点在图像中的位置。

之后使用:

[html]  view plain  copy
  1. KLTSelectGoodFeatures(tc, img1, ncols, nrows, fl);  

使用上面的函数选取特征点

[html]  view plain  copy
  1. KLTTrackFeatures(tc, img1, img2, ncols, nrows, fl);  

使用这个函数在img2中寻找对应的特征点。

一次循环就可以实现跟踪了。

那么出现了一个问题:特征点是怎么定义的:

我们分析KLTSelectGoodFeatures这个函数:

函数中又使用了:

[html]  view plain  copy
  1. _KLTSelectGoodFeatures(tc, img, ncols, nrows,   
  2.                          fl, SELECTING_ALL);  


这个函数,函数中首先见了了一个pointlist的分量,并分配了内存空间:

[html]  view plain  copy
  1. pointlist = (int *) malloc(ncols * nrows * 3 * sizeof(int));  

为什么要*3呢?其实pointlist中存了图像中点的位置x,y和特征值的大小val。

特征值是什么呢?这个特征是就是对应像素点的梯度值。

[html]  view plain  copy
  1. {  
  2.     register float gx, gy;  
  3.     register float gxx, gxy, gyy;  
  4.     register int xx, yy;  
  5.     register int *ptr;  
  6.     float val;  
  7.     unsigned int limit = 1;  
  8.     int borderx = tc->borderx;   /* Must not touch cols */  
  9.     int bordery = tc->bordery;   /* lost by convolution */  
  10.     int x, y;  
  11.     int i;  
  12.       
  13.     if (borderx < window_hw)  borderx = window_hw;  
  14.     if (bordery < window_hh)  bordery = window_hh;  
  15.   
  16.     /* Find largest value of an int */  
  17.     for (i = 0 ; i < sizeof(int) ; i++)  limit *= 256;  
  18.     limit = limit/2 - 1;  
  19.           
  20.     /* For most of the pixels in the image, do ... */  
  21.     ptr = pointlist;  
  22.     for (y = bordery ; y < nrows - bordery ; y += tc->nSkippedPixels + 1)  
  23.       for (x = borderx ; x < ncols - borderx ; x += tc->nSkippedPixels + 1)  {  
  24.   
  25.         /* Sum the gradients in the surrounding window */  
  26.         gxx = 0;  gxy = 0;  gyy = 0;  
  27.         for (yy = y-window_hh ; yy <= y+window_hh ; yy++)  
  28.           for (xx = x-window_hw ; xx <= x+window_hw ; xx++)  {  
  29.             gx = *(gradx->data + ncols*yy+xx);  
  30.             gy = *(grady->data + ncols*yy+xx);  
  31.             gxx += gx * gx;  
  32.             gxy += gx * gy;  
  33.             gyy += gy * gy;  
  34.           }  
  35.   
  36.         /* Store the trackability of the pixel as the minimum  
  37.            of the two eigenvalues */  
  38.         *ptr++ = x;  
  39.         *ptr++ = y;  
  40.         val = _minEigenvalue(gxx, gxy, gyy);  
  41.         if (val > limit)  {  
  42.           KLTWarning("(_KLTSelectGoodFeatures) minimum eigenvalue %f is "  
  43.                      "greater than the capacity of an int; setting "  
  44.                      "to maximum value", val);  
  45.           val = (float) limit;  
  46.         }  
  47.         *ptr++ = (int) val;  
  48.         npoints++;  
  49.       }  

代码中的特征值取得时每个像素点临域梯度值的加权值。

之后程序来到了函数:

[html]  view plain  copy
  1. _enforceMinimumDistance(  
  2.    pointlist,  
  3.    npoints,  
  4.    featurelist,  
  5.    ncols, nrows,  
  6.    tc->mindist,  
  7.    tc->min_eigenvalue,  
  8.    overwriteAllFeatures);  

这里通过比较每个像素点val和对应阈值的大小来提取特征点:

[html]  view plain  copy
  1. if (!featuremap[y*ncols+x] && val >= min_eigenvalue)  {  
  2.       featurelist->feature[indx]->x   = (KLT_locType) x;  
  3.       featurelist->feature[indx]->y   = (KLT_locType) y;  
  4.       featurelist->feature[indx]->val = (int) val;  
  5.       featurelist->feature[indx]->aff_img = NULL;  
  6.       featurelist->feature[indx]->aff_img_gradx = NULL;  
  7.       featurelist->feature[indx]->aff_img_grady = NULL;  
  8.       featurelist->feature[indx]->aff_x = -1.0;  
  9.       featurelist->feature[indx]->aff_y = -1.0;  
  10.       featurelist->feature[indx]->aff_Axx = 1.0;  
  11.       featurelist->feature[indx]->aff_Ayx = 0.0;  
  12.       featurelist->feature[indx]->aff_Axy = 0.0;  
  13.       featurelist->feature[indx]->aff_Ayy = 1.0;  
  14.       indx++;  

min_eigenvalue就是所使用的阈值,在tc中定义

那么程序的修改,我们需要根据自己的特征对这个阈值进行修改,同时对featurelist进行如上的修改,其实主要还是x,y,val三个值的修改。

不对的地方请大家指正。


猜你喜欢

转载自blog.csdn.net/yin_hei/article/details/57128213