OpenCV温故而知新: 异常对象侦测

这个异常对象侦测通常可被广泛用于诸如银行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键中止。

Author: Jacky Wei

I am a programmer, welcome to my blog: http://rg4.net.

Leave a Reply

Your email address will not be published. Required fields are marked *