3
我正試圖實現代碼簿前景檢測算法概述here在書學習OpenCV。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示例中有一個相同算法的示例實現。但是,這種結構似乎要複雜得多。我正在更多地瞭解這種方法背後的原因,我知道我可以修改實際應用的樣本。
感謝
但是,是否有任何關於此實施的重要事情正在放慢速度?示例部分中的示例代碼運行速度快得多,但實現了我認爲基本相同的想法... – amatsukawa 2010-09-07 04:23:08
不。您的循環之外的任何內容對於速度優化而言都可以忽略不計。 – 2010-09-07 04:25:04