这个异常对象侦测通常可被广泛用于诸如银行ATM机上的非法广告张贴等情景,但是同其他的一些算法一样,容易受到一些客观条件的干扰,如:灯光、光线,物体形状,物体大小等等,我们可以对这些参数做设置和配置,但是在各种不同的情景和场景下,仍然有比较大的误报可能性。
同时考虑到可能的误报,侦测背景也是做成了逐渐腐蚀渗透,即,一旦发生报警,而没有人去处理(可能是误报),就直接将该区域混合到计算背景中,以期在最大程度上降低误报的可能性(如:因白天的光亮度和晚上光亮度不一样而导致的整体误报)。
以下是接口说明。
全域类别说明:
class ObjectInformation{ //存放对象的各项信息
public:
ObjectInformation() { objImage = cvCreateImage( cvSize(100,100), IPL_DEPTH_8U, 3); }
int X; //对象的X坐标
int Y; //对象的Y坐标
int State; //对象目前的状态; 0→初始状态
1→找到物件
2→发出警告
-1→取消物件
int Time; //纪录找到对象时的时间点
int objWidth; //物件的宽度
int objHeight; //物件的高度
int cancel_object_flag; //判断是否执行取消对象警告的处理 ; 0→不执行
1→执行
int object_selection_flag; //判断是否选择到该对象 ; 0→不执行
1→执行
int Updata_CancelObject_count; //执行取消对象时,该对象被updata成背景的次数
IplImage* objImage; //存物件的图
SYSTEMTIME AlarmTime; //纪录发出警告时的时间点
~ObjectInformation() { cvReleaseImage(&objImage); }
};
class CAbnormalDetect{ //异常对象的类别成员与函式
private:
int nWidth, nHeight; //frame的宽与高
int UpdateCount;
int FrameIntervalCount;
int WindowSize; //计算光流值时,撷取的区块大小
IplImage *LastFrame;
IplImage *ObjcetProb; //存放停滞不动统计的值
int nSeconds; //静止物体持续多少秒才算是异常对象
int nSeconds2; //异常物件框选多少秒后取消该框选
int mFrameCount;
CvSize nScale; //只侦测比这个值大的对象
int FrameRate; //frame rate
int Train_BgModel_number; //计算建背景所需的frame张数
double weight; //计算初始时背景模型的权重值
IplImage* CurrentImage; //当前frame
IplImage* BackgroundImage; //背景
IplImage* ForegroundImage; //前景
public:
CAbnormalDetect(int, int); //建构子
~CAbnormalDetect(); //解构子
ObjectInformation ObjInf[objectNumber]; //宣告对象类别
void SetObjectSize(CvSize); //设定对象大小
void SetImage(IplImage *); //设定影像数据
IplImage* GetImage(int); //取得影像数据
bool UnderInitializing(); //初始化(建立背景)
bool Alarm(); //判断是否有警告
void UpdateBackgroundImage(IplImage*,IplImage*,IplImage*,int,int,double); //建背景影像与更新
void GetForeground(IplImage*, IplImage*, IplImage*, int); //取得前景影像
void FindObject(IplImage*, IplImage*); //找异常对象并记录其各项信息
void ShowAlarm(IplImage*, IplImage*, IplImage*, int); //判断是否显示警告
void HandCancelObject(IplImage*, IplImage*, int, int); //处理手动取消对象时的程序
void AutomaticCancelObject(IplImage*,IplImage*,int,int,int,int);//处理自动取消对象时的程序
void ClearObjectInf(int); //归零各项参数
void Re_rankingObject(); //重新排序对象编号与其参数
bool ObjectCase(IplImage*, IplImage*, IplImage*, int, int); //考虑该不该发警告
};
成员函式说明
CAbnormalDetect::CAbnormalDetect(int width, int height, int seconds1, int seconds2){
目的: 初始化程序中会使用到的参数—建构子
用法: 给定初始值
参数:
Parameter |
Type |
Description |
width |
int |
frame的宽 |
height |
int |
frame的高 |
seconds1 |
int |
静止物体持续多少秒才算是异常对象 |
seconds2 |
int |
异常物件框选多少秒后取消该框选 |
}
CAbnormalDetect::~CAbnormalDetect(){
目的: 释放宣告的内存空间—解构子
}
void CAbnormalDetect::SetImage(IplImage *SourceImg){
目的: 设定影像数据
参数:
Parameter |
Type |
Description |
SourceImg |
IplImage |
输入的来源影像 |
}
IplImage* CAbnormalDetect::GetImage(int index){
目的: 取得影像数据
用法: 配合传入的index值,来决定输出何种影像
参数:
Parameter |
Type |
Description |
index |
int |
决定输出何种影像 |
Return:
Status |
Condition |
index=1 |
读取当前frame |
index=2 |
读取背景 |
index=3 |
读取前景 |
}
void CAbnormalDetect::SetObjectSize(CvSize size){
目的: 设定对象大小
用法: 直接给定对象大小的参数
参数:
Parameter |
Type |
Description |
size |
CvSize |
物件的大小 |
}
bool CAbnormalDetect::UnderInitializing(IplImage *SourceImg, IplImage *ForegroundImg, IplImage* BackgroundImg, int Train_BgModel_number, int FrameRate, double weight){
目的: 初始化(建立背景影像)
用法: 利用所传入的来源影像(SourceImg)与前景影像(ForegroundImg),来建构背景影像模型,搭配权重(weight)来调整收敛速度与效果
参数:
Parameter |
Type |
Description |
SourceImg |
IplImage |
输入的来源影像 |
ForegroundImg |
IplImage |
输入的前景影像 |
BackgroundImg |
IplImage |
存放处理完的背景影像 |
Train_BgModel_number |
int |
建背景所需的frame张数 |
FrameRate |
int |
每秒frame的张数 |
weight |
double |
建背景模型时的权重 |
Return:
Status |
Condition |
true |
正在建背景影像 |
false |
完成初始化 |
}
bool CAbnormalDetect::Alarm(IplImage *SourceImg, IplImage *ForegroundImg, IplImage* BackgroundImg){
目的: 判断是否有警告
用法: 利用所传入的来源影像(SourceImg)、前景影像(ForegroundImg)与背景影像(BackgroundImg),来判断是否有警告发生
参数:
Parameter |
Type |
Description |
SourceImg |
IplImage |
来源影像 |
ForegroundImg |
IplImage |
前景影像 |
BackgroundImg |
IplImage |
背景影像 |
Return:
Status |
Condition |
true |
需要发警告 |
false |
不需要发警告 |
}
void CAbnormalDetect::UpdateBackgroundImage(IplImage *SourceImage, IplImage *foregroundImg, IplImage* BackgroundImage, int IntervalFrame, int select, double alpha){
目的: 建背景影像与更新
用法: 利用所传入的来源影像(SourceImage)与前景影像(foregroundImg),来建构背景影像模型,可搭配影像间隔(IntervalFrame)与权重(alpha)来调整收敛速度与效果
参数:
Parameter |
Type |
Description |
SourceImage |
IplImage |
输入的来源影像 |
foregroundImg |
IplImage |
输入的前景影像 |
BackgroundImage |
IplImage |
存放处理完的背景影像 |
IntervalFrame |
int |
间隔多少张frame执行一次 |
select |
int |
select=0:使用于初始,建背景模型 select=1:使用于后续,间隔一段时 间更新背景 |
alpha |
double |
建背景模型时的权重 |
}
void CAbnormalDetect::GetForeground(IplImage* sourceImg, IplImage* backgroundImgModel, IplImage* foregroundImg, int background_thresh){
目的: 取得前景影像
用法: 利用所传入的来源影像(sourceImg)与背景影像(backgroundImgModel),做背景相减法,并搭配threshold来产生前景影像,放置于foregroundImg的内存指针区块内
参数:
Parameter |
Type |
Description |
sourceImg |
IplImage |
输入的来源影像 |
backgroundImgModel |
IplImage |
输入的背景影像 |
foregroundImg |
IplImage |
存放处理完的前景影像 |
background_thresh |
int |
判断为前景的threshold |
}
void CAbnormalDetect::FindObject(IplImage* CurFrame, IplImage* foregroundImg){
目的: 找异常对象并记录其各项信息
用法: 利用所传入的来源影像(CurFrame)与前景影像(foregroundImg),做光流值的运算,找出停滞不动的对象,并纪录该对象的各项信息
参数:
Parameter |
Type |
Description |
CurFrame |
IplImage |
输入的来源影像 |
foregroundImg |
IplImage |
输入的前景影像 |
}
void CAbnormalDetect::ShowAlarm(IplImage* CurFrame, IplImage* BackgroundImage, IplImage* ForegroundImage, int IntervalTime){
目的: 判断是否显示警告
用法: 利用所传入的来源影像(CurFrame)、背景影像(BackgroundImage)与前景影像(foregroundImg)来做判断,判断在间隔N秒的时间内是否发出警告
参数:
Parameter |
Type |
Description |
CurFrame |
IplImage |
输入的来源影像 |
BackgroundImage |
IplImage |
输入的背景影像 |
ForegroundImage |
IplImage |
输入的前景影像 |
IntervalTime |
int |
间隔N秒的时间 |
}
bool CAbnormalDetect::ObjectCase(IplImage* CurFrame, IplImage* BackgroundImage, IplImage* ForegroundImage, int x, int y){
目的: 考虑该不该发警告
用法: 利用所传入的来源影像(CurFrame)、背景影像(BackgroundImage)与前景影像(foregroundImg)来判断物体目前的情况
参数:
Parameter |
Type |
Description |
CurFrame |
IplImage |
输入来源影像 |
BackgroundImage |
IplImage |
输入背景影像 |
ForegroundImage |
IplImage |
输入前景影像 |
x |
int |
对象的坐标X |
y |
int |
对象的坐标Y |
Return:
Status |
Condition |
true |
发alarm |
false |
不发alarm |
}
void CAbnormalDetect::HandCancelObject(IplImage* CurFrame, IplImage* BackgroundImage, int ObjNumber, int UpdataInterval){
目的: 处理手动取消对象时的程序
用法: 用手动的方式去点选发警告的区块,取消该区块并将对象更新至背景模型上
参数:
Parameter |
Type |
Description |
CurFrame |
IplImage |
输入来源影像 |
BackgroundImage |
IplImage |
输入背景影像 |
ObjNumber |
int |
第N个物件 |
UpdataInterval |
int |
对象图像更新的次数 |
}
void CAbnormalDetect::AutomaticCancelObject(IplImage* CurFrame, IplImage* BackgroundImage, int index, int m_Minute, int m_Second, int UpdataInterval){
目的: 处理自动取消对象时的程序
用法: 以自动的方式来执行(间隔N分N秒的时间),并自动取消该区块警告并将对象更新至背景模型上
参数:
Parameter |
Type |
Description |
CurFrame |
IplImage |
输入来源影像 |
BackgroundImage |
IplImage |
输入背景影像 |
index |
int |
第N个物件 |
m_Minut |
int |
间隔N分 |
m_Second |
int |
间隔N秒 |
UpdataInterval |
int |
对象图像更新的次数 |
}
void CAbnormalDetect::ClearObjectInf(int index){
目的: 归零各项参数
用法: 传入第N个对象的编号,将该对象的各项信息全部归零
参数:
Parameter |
Type |
Description |
index |
int |
第N个物件 |
}
void CAbnormalDetect::Re_rankingObject(){
目的: 重新排序对象编号与其参数
用法: 重新排序对象,当对象的前一个是空的时,后面的物件往前挪
}
测试程序及序列
测试程序: http://rg4.net/p/easyiv/libabnormaldetect_test.7z
测试视频序列:http://rg4.net/p/easyiv/libabnormaldetect_sample.avi
测试程序说明:
- 指定测试视频:libabnormaldetect_test.exe 111.avi,这个111.avi是你输入的视频文件。若不指定则默认打开当前目录下的libabnormaldetect_sample.avi文件,若这个文件不存在则打开电脑上的摄像头。
- 测试程序快捷键:按r重新设定ROI检测区域,按p暂停处理,按t or ESC键中止。