Обнаружение OpenCV Foreground медленное - PullRequest
3 голосов
/ 07 сентября 2010

Я пытаюсь реализовать алгоритм обнаружения переднего плана кодовой книги, описанный здесь в книге Обучение 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 приведен пример реализации того же алгоритма. Однако эта структура кажется гораздо более сложной. Я хочу больше понять причины этого метода, я знаю, что могу просто изменить образец для реальных приложений.

Спасибо

1 Ответ

0 голосов
/ 07 сентября 2010

Работа с каждым пикселем изображения будет медленной, независимо от того, как вы ее реализуете.

...