基于HSI色彩空间的去阴影方法
2013-11-14 16:44
323 查看
基本原理:阴影区域颜色的色调信息H和饱和度信息S具有较小的变动,而亮度信息I会有较大的变换,但是HS基本上包含了颜色信息。根据这个特点,在检测某一个像素是否为阴影时,只需要判断该像素是否满足‘H、S分量浮动较小,而I变化幅度较大’就可以。阴影检测函数:currImg:当前帧bkImg:背景帧shadowdeImg:检测到的阴影区域th1,th2:亮度比的阈值th3:色调差的阈值th4:饱和度差的阈值void ShadowDetect(IplImage *currImg, IplImage *bkImg, IplImage *shadowdeImg,double th1,double th2,double th3,double th4)
{
cvZero(shdadeImg);
cvNot(shdadeImg,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,bf=0;
double rt=0,gt=0,It=0,Rt=0,Gt=0,Bt=0,tf=0;
//CvScalar cs=cvScalarAll(255);
for (i=0;i<height;i++)
{
currData=(unsigned char*)currImg->imageData+i*currImg->widthStep; //指针为第i+1行
bkData=(unsigned char*)bkImg->imageData+i*bkImg->widthStep;
shadeData=(unsigned char*)shdadeImg->imageData+i*shdadeImg->widthStep;
for (j=0;j<width;j++)
{
// current normalized
//*******************
//当前图像
//*******************
Bt=currData[j*3]; //分别获取像素点的BGR值
Gt=currData[j*3+1];
Rt=currData[j*3+2];
tf=(Rt>Gt?Gt:Rt)>Bt?Bt:(Rt>Gt?Gt:Rt); //取R、G、B三值中的最小值存入tf
rt=acos((0.5*((Rt-Gt)+(Rt-Bt)))/(sqrt((Rt-Gt)*(Rt-Gt)+(Rt-Bt)*(Rt-Gt)))); //求色调(2pi-theta?) H
gt=1-3*tf/(Rt+Gt+Bt); //求饱和度 S
It=(Rt+Gt+Bt)/3; //求亮度 I
// Bk normalized
//*********************
//背景图像
//*********************
Bb=bkData[j*3];
Gb=bkData[j*3+1];
Rb=bkData[j*3+2];
bf=(Rb>Gb?Gb:Rb)>Bb?Bb:(Rb>Gb?Gb:Rb);
rb=acos((0.5*((Rb-Gb)+(Rb-Bb)))/(sqrt((Rb-Gb)*(Rb-Gb)+(Rb-Bb)*(Rb-Gb))));
gb=1-3*bf/(Rb+Gb+Bb);
Ib=(Rb+Gb+Bb)/3;
// judge whether is shadeimg
//判断
if (It/Ib>=th1&& It/Ib<=th2 && fabs(rt-rb)<=th3 && fabs(gt-gb)<=th4)
{
shadeData[j*3]=0;
shadeData[j*3+1]=0;
shadeData[j*3+2]=0;
}
}
}
}
{
cvZero(shdadeImg);
cvNot(shdadeImg,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,bf=0;
double rt=0,gt=0,It=0,Rt=0,Gt=0,Bt=0,tf=0;
//CvScalar cs=cvScalarAll(255);
for (i=0;i<height;i++)
{
currData=(unsigned char*)currImg->imageData+i*currImg->widthStep; //指针为第i+1行
bkData=(unsigned char*)bkImg->imageData+i*bkImg->widthStep;
shadeData=(unsigned char*)shdadeImg->imageData+i*shdadeImg->widthStep;
for (j=0;j<width;j++)
{
// current normalized
//*******************
//当前图像
//*******************
Bt=currData[j*3]; //分别获取像素点的BGR值
Gt=currData[j*3+1];
Rt=currData[j*3+2];
tf=(Rt>Gt?Gt:Rt)>Bt?Bt:(Rt>Gt?Gt:Rt); //取R、G、B三值中的最小值存入tf
rt=acos((0.5*((Rt-Gt)+(Rt-Bt)))/(sqrt((Rt-Gt)*(Rt-Gt)+(Rt-Bt)*(Rt-Gt)))); //求色调(2pi-theta?) H
gt=1-3*tf/(Rt+Gt+Bt); //求饱和度 S
It=(Rt+Gt+Bt)/3; //求亮度 I
// Bk normalized
//*********************
//背景图像
//*********************
Bb=bkData[j*3];
Gb=bkData[j*3+1];
Rb=bkData[j*3+2];
bf=(Rb>Gb?Gb:Rb)>Bb?Bb:(Rb>Gb?Gb:Rb);
rb=acos((0.5*((Rb-Gb)+(Rb-Bb)))/(sqrt((Rb-Gb)*(Rb-Gb)+(Rb-Bb)*(Rb-Gb))));
gb=1-3*bf/(Rb+Gb+Bb);
Ib=(Rb+Gb+Bb)/3;
// judge whether is shadeimg
//判断
if (It/Ib>=th1&& It/Ib<=th2 && fabs(rt-rb)<=th3 && fabs(gt-gb)<=th4)
{
shadeData[j*3]=0;
shadeData[j*3+1]=0;
shadeData[j*3+2]=0;
}
}
}
}
相关文章推荐
- cocos2d-x 内存管理
- 判断特定窗口是否存在、线程中获取获得一个顶层窗口的句柄
- 在MFC中操作.ini文件
- 车道检测过程中遇到的问题
- MFC对话框中,将图片无变形地显示在图片控件框中(也适用于视频)
- BT服务器源码分析
- ID3DXMesh接口 创建自己的立方体网格
- [JavaScript] JS实现上传图片及时预览
- Servlet生命周期
- 采用Filter统一验证是否登录
- Hough变换原理---从图像中识别几何图形,确定其参数
- 大津法---OTSU算法
- 关于inline---代替宏定义
- 在word中,怎么插入一条水平线、粗线、波浪线、双直线、虚线 -------自动边框线
- Opencv2.3.1在VS2010平台上安装配置图解(64位系统)
- 遇到的问题------基于OPENCV的车流量识别
- MFC打开文件对话框
- 修改win7开机界面打造属于自己风格的win7开机动画
- Altium中 PCB的覆铜步骤与注意点
- [转]matlab中plot用法