ここで本Learning OpenCVで概説されているコードブック前景検出アルゴリズムを実装しようとしています。
このアルゴリズムは、画像の各ピクセルに対するコードブック ベースのアプローチのみを記述します。そこで、思いついた最も単純な方法を採用しました。IplImage の基礎となるマトリックス構造によく似た、ピクセルごとに 1 つずつ、コードブックの配列を用意することです。配列の長さは、画像のピクセル数と同じです。
背景を学習し、前景をセグメント化するために、次の 2 つのループを作成しました。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 倍にすると、プログラムはピクセルごとに 2 ずつ遅くなり、ピクセル数によって拡大されます。しかし、実装の現状では、コード要素のエントリを並べ替えるための明確で論理的な方法は見当たりません。
opencv サンプルに同じアルゴリズムの実装例があることは承知しています。しかし、その構造ははるかに複雑なようです。この方法の背後にある理由を理解するためにもっと探しています。実際のアプリケーション用にサンプルを変更するだけでよいことを認識しています。
ありがとう