3

我正在尝试实现Learning OpenCV一书中概述码本前景检测算法。

该算法仅针对图片的每个像素描述了基于码本的方法。所以我采用了想到的最简单的方法——拥有一组码本,每个像素一个,很像 IplImage 的矩阵结构。数组的长度等于图像中的像素数。

我写了以下两个循环来学习背景和分割前景。它利用了我对 src 图像内部矩阵结构的有限理解,并使用指针算法来遍历像素。

  void foreground(IplImage* src, IplImage* dst, codeBook* c, int* minMod, int* maxMod){

 int height = src->height;
 int width = src->width;

 uchar* srcCurrent = (uchar*) src->imageData;
 uchar* srcRowHead = srcCurrent;
 int srcChannels = src->nChannels;
 int srcRowWidth = src->widthStep;

 uchar* dstCurrent = (uchar*) dst->imageData;
 uchar* dstRowHead = dstCurrent;
 // dst has 1 channel
 int dstRowWidth = dst->widthStep;

 for(int row = 0; row < height; row++){
  for(int column = 0; column < width; column++){
   (*dstCurrent) = find_foreground(srcCurrent, (*c), srcChannels, minMod, maxMod);
   dstCurrent++;
   c++;
   srcCurrent += srcChannels;
  }
  srcCurrent = srcRowHead + srcRowWidth;
  srcRowHead = srcCurrent;
  dstCurrent = dstRowHead + dstRowWidth;
  dstRowHead = dstCurrent;
 }
}

void background(IplImage* src, codeBook* c, unsigned* learnBounds){

 int height = src->height;
 int width = src->width;

 uchar* srcCurrent = (uchar*) src->imageData;
 uchar* srcRowHead = srcCurrent;
 int srcChannels = src->nChannels;
 int srcRowWidth = src->widthStep;

 for(int row = 0; row < height; row++){
  for(int column = 0; column < width; column++){
   update_codebook(srcCurrent, c[row*column], learnBounds, srcChannels);
   srcCurrent += srcChannels;
  }
  srcCurrent = srcRowHead + srcRowWidth;
  srcRowHead = srcCurrent;
 }
}

该程序有效,但非常缓慢。有什么明显的东西在减慢速度吗?还是简单实现中的固有问题?我有什么办法可以加快速度吗?每个码本都没有按特定顺序排序,因此处理每个像素确实需要线性时间。因此,将背景样本加倍,程序对每个像素的运行速度减慢 2,然后将其放大像素数。但就实现而言,我看不到任何清晰、合乎逻辑的方式来对代码元素条目进行排序。

我知道在 opencv 示例中有相同算法的示例实现。然而,这种结构似乎要复杂得多。我希望更多地了解这种方法背后的原因,我知道我可以为现实生活中的应用程序修改示例。

谢谢

4

1 回答 1

0

无论您如何实现它,对图像中的每个像素进行操作都会很慢。

于 2010-09-06T23:50:38.093 回答