在智能視頻分析系統的研究過程當中,尤爲是對於一些工程應用來講,光照的忽然變化是一個很棘手的問題。儘管,很多學者對光照的忽然變化進行了大量的研究,並且也提出了相關的光照不變的算法(illumination invariant),對解決這類問題提供了必定的思路。通常都是經過計算光照不變特徵來實現,文章包括:css
1)An Illumination Invariant Change Detection Algorithm.html
2)Bayesian Illumination-Invariant Motion Detection.ios
3)robust and illumination invariant change detection based on linear dependence for surveillance application.算法
4)reflectance ratio-a photometric invariant for object recognition_ICCV93.數據結構
5)computing reflectance ratios from an image_PR93.app
6)Color Invariant Edge Detectionui
7)Learning Photometric Invariance for Object Detection-IJCV2010
spa
8)making background subtraction robust to sudden illumination changes.net
9)Object Detection Using Local Difference Patterns.
視頻
儘管,以上論文中的方法都聲稱對光照變化具備不變性,可是在實際中,有不少是靠不住的,可能說對緩慢光照的變化具備必定的魯棒性更準確。有些算法的複雜度也是可待商榷的(如making background subtraction robust to sudden illumination changes)。
根據實際狀況,本文提出兩種解決光照忽然變化的方法,一是多模式的背景模型,二是背景重建,我想這也應該是工程中應用較多的途徑和思路吧。
多模式背景模型就是對一個場景創建多種環境下的背景模型,算法檢測環境的變化,自動選擇背景模型。如對於光照條件正常的狀況創建一個背景模型,進行保存;而對於背景較暗的狀況創建一個背景模型,也進行保存;若是有多種狀況,就創建多個背景模型。(而對於緩慢的光照變化如今應該有不少算法可以處理)。
而對另外的背景重建的思路,如今已經有至關廣泛的算法可以就一幀創建起背景模型(如SOBS、VIBE等)。在檢測到有忽然光照變化的狀況下,就進行背景模型的重建,接着對運動進行檢測。然而,在這種狀況下,比較棘手的問題是如何判斷光照的變化,不少論文上說的採用前景像素佔整個圖像大小的比例做爲依據,然而該方法在實際中也經常誤判率較高。本文介紹一種思路,並且通過試驗也很不錯,相比比率方法有了很多提升。
思路以下:將整個圖片進行分塊,統計每一塊的前景像素個數,當某塊的前景像素大於某一個閾值時,則計數器+1,依次遍歷整個圖像,統計獲得計數器的值,計算機計算器與整個圖像塊數的比值,比值大於某一閾值,則判斷爲光照突變。
核心代碼以下:
1)圖像分塊
// winSize default 32
void buildGrid( const Mat& input, vector<Rect>& grid, int winSize=32 )
{
grid.clear();
int height = input.rows;
int width = input.cols;
Rect rc;
for ( int i=0; i<height; i=i+winSize)
{
for ( int j=0; j<width; j=j+winSize )
{
rc.y = i;
rc.x = j;
if (rc.x + winSize>width-1)
rc.width = width-rc.x-1;
else
rc.width = winSize;
if (rc.y+winSize>height)
rc.height = height-rc.y-1;
else
rc.height = winSize;
grid.push_back(rc);
}
}
}
2)計算比值
// winSize default 32, ratio default 1.0/winSize
bool isSuddenChange( const vector<Rect>& grid, Mat& foreground, int winSize=32, double ratio=1.0/32.0)
{
int count = 0;
int gridSize = grid.size();
for ( int i=0; i<gridSize; ++i )
{
int nonZero = countNonZero( foreground(grid[i]));
double _r = double(nonZero)/(double)(winSize*winSize);
//if ( nonZero>32)
if ( _r> ratio)
count++;
}
double ratio = (double)count/(float)gridSize;
cout<<" NonZero ratio: "<<ratio<<endl;
if ( ratio > 0.60 )
{
imwrite("fore.jpg",foreground);
return true;
}
return false;
}
轉載請註明出處:http://blog.csdn.net/kezunhai