在运动目标检测中,常常会出现由于光线被遮挡,或场景其他物体的遮挡,在目标附近或场景里出现阴影,阴影的出现对后期目标的正确分割与处理带了很大的不便。如今,国内外已有不少文献来研究这个问题,并且提出了各种各样的阴影去除算法。本文就其中的一种算法提出了一个通用的实现算法,该算法考虑了背景与前景颜色相近的情况,希望能给大家一些帮助:(介绍下算法的思路:算法首先对RGB颜色空间的值进行归一化处理,即:r=R/(R+G+B),g=G/(R+G+B), I=(R+G+B)/3。然后利用背景和当前帧r,g的插值和I的比例来确定阴影区域:
详细细节请参考文献:Detecting moving objects,ghosts and shadows in video streams
// shadeImg is a binary image,the value th2 and th3 are chosen empirically here,set th2=0.6 th3=1.5, th4=7
void ShadeDetect(IplImage *currImg, IplImage *bkImg, IplImage *shdadeImg,double th1,double th2,double th3,double th4)
{
cvZero(shdadeImg);
unsigned char* currData;
unsigned char* bkData;
unsigned char* shadeData;
int i=0,j=0;
int height=currImg->height;
int width=currImg->width;
double rb=0,gb=0,Ib=0,Rb=0,Gb=0,Bb=0;
double rt=0,gt=0,It=0,Rt=0,Gt=0,Bt=0;
//CvScalar cs=cvScalarAll(255);
for (i=0;i<height;i++)
{
currData=(unsigned char*)currImg->imageData+i*currImg->widthStep;
bkData=(unsigned char*)bkImg->imageData+i*bkImg->widthStep;
shadeData=(unsigned char*)shdadeImg->imageData+i*shdadeImg->widthStep;
for (j=0;j<width;j++)
{
// current normalized
Rt=currData[j*3];
Gt=currData[j*3+1];
Bt=currData[j*3+2];
rt=Rt/(Rt+Gt+Bt);
gt=Gt/(Rt+Gt+Bt);
It=(Rt+Gt+Bt)/3;
// Bk normalized
Rb=bkData[j*3];
Gb=bkData[j*3+1];
Bb=bkData[j*3+2];
rb=Rb/(Rb+Gb+Bb);
gb=Gb/(Rb+Gb+Bb);
Ib=(Rb+Gb+Bb)/3;
// judge whether is shadeimg
if (fabs(rt-rb)<=th1 && fabs(gt-gb)<th1 && It/Ib>=th2 && It/Ib<=th3 && fabs(It-Bt)<th4)
{
shadeData[j]=255;
}
}
}
}
{
cvZero(shdadeImg);
unsigned char* currData;
unsigned char* bkData;
unsigned char* shadeData;
int i=0,j=0;
int height=currImg->height;
int width=currImg->width;
double rb=0,gb=0,Ib=0,Rb=0,Gb=0,Bb=0;
double rt=0,gt=0,It=0,Rt=0,Gt=0,Bt=0;
//CvScalar cs=cvScalarAll(255);
for (i=0;i<height;i++)
{
currData=(unsigned char*)currImg->imageData+i*currImg->widthStep;
bkData=(unsigned char*)bkImg->imageData+i*bkImg->widthStep;
shadeData=(unsigned char*)shdadeImg->imageData+i*shdadeImg->widthStep;
for (j=0;j<width;j++)
{
// current normalized
Rt=currData[j*3];
Gt=currData[j*3+1];
Bt=currData[j*3+2];
rt=Rt/(Rt+Gt+Bt);
gt=Gt/(Rt+Gt+Bt);
It=(Rt+Gt+Bt)/3;
// Bk normalized
Rb=bkData[j*3];
Gb=bkData[j*3+1];
Bb=bkData[j*3+2];
rb=Rb/(Rb+Gb+Bb);
gb=Gb/(Rb+Gb+Bb);
Ib=(Rb+Gb+Bb)/3;
// judge whether is shadeimg
if (fabs(rt-rb)<=th1 && fabs(gt-gb)<th1 && It/Ib>=th2 && It/Ib<=th3 && fabs(It-Bt)<th4)
{
shadeData[j]=255;
}
}
}
}