2011-10-14 174 views
7

我想要實現背景平均法。我在一秒鐘內拍攝了50幀圖像,其中一些幀包含我想要提取爲前景的閃電。使用固定攝像機拍攝框架,並將框架視爲灰度。我想要做的是:OpenCV中的背景減法(C++)

  1. 獲取背景模型
  2. 後,比較每一幀的背景模型,以確定是否有在該框架或不點亮。

我讀了一些關於如何通過使用cvAcc()來完成這項工作的文檔,但我很難理解如何做到這一點。我將不勝感激指導我的一段代碼,並鏈接到可幫助我理解如何實現這一點的文檔。

感謝您提前。

回答

18

我們在其中一個項目中完成了相同的任務。爲了得到背景模型,我們只需創建一個BackgroundModel類,捕獲第一個(可以說)50幀並計算平均幀,以避免背景模型中的像素錯誤。例如,如果您從相機獲取8位灰度圖像(CV_8UC1),則使用CV_16UC1初始化模型以避免裁剪。現在

cv::Mat model = cv::Mat(HEIGHT, WIDTH, CV_16UC1, cv::Scalar(0)); 

,等待第一個幀,計算模型,只是每幀添加到模型並計算接收幀的數量。

void addFrame(cv::Mat frame) { 
    cv::Mat convertedFrame; 
    frame.convertTo(convertedFrame, CV_16UC1); 
    cv::add(convertedFrame, model, model); 
    if (++learnedFrames >= FRAMES_TO_LEAN) { // FRAMES_TO_LEARN = 50 
     createMask(); 
    } 
} 

createMask()函數計算我們用於模型的平均幀。

void createMask() { 
    cv::convertScaleAbs(model, mask, 1.0/learnedFrames); 
    mask.convertTo(mask, CV_8UC1); 
} 

現在,您只需將所有幀通過BackgroundModel類發送到函數subtract()即可。如果結果是一個空的cv :: Mat,則仍然計算掩碼。否則,你會得到一個相減的幀。

cv::Mat subtract(cv::Mat frame) { 
    cv::Mat result; 
    if (++learnedFrames >= FRAMES_TO_LEAN) { // FRAMES_TO_LEARN = 50 
     cv::subtract(frame, mask, result); 
    } 
    else { 
     addFrame(frame); 
    } 
    return result; 
} 

最後但並非最不重要的,你可以使用 標量和(常量墊& MTX) 用於計算像素之和決定它是否與它的燈光的框架。

+0

非常感謝你ping(「,) – user854576

+3

@ user854576如果這是一個正確的答案,你應該很好,並接受它。見[本頁](http://stackoverflow.com/faq#howtoask)在常見問題如何接受答案。 –