原理:
該方法在實作過程中主要結合了車輛陰影的4個特性:
(1) 陰影的亮度值比背景的亮度值小;
(2) 運動陰影與背景的梯度密度差低于運動車輛與背景的梯度密度差;
(3) 陰影在車輛的周圍區域,即可以在車輛外部的任意方向,但不在車輛
内部區域;
(4) 陰影的邊緣像素比車輛的邊緣像素少。
代碼:
"main.h"
#include "highgui.h"
#include "cv.h"
#include "cxcore.h"
#include <math.h>
#define TEMPLATEM 3
#define TEMPLATEN 3
"main,cpp"
#include "main.h"
int main(int argc,int **argv)
{
IplImage *img =cvLoadImage("F:\\testData\\test.BMP");
IplImage *gray=cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);
IplImage *backgray=cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);
IplImage *binedge=cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);
IplImage *differgray=cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);
IplImage *edgegray=cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_16S,1);
IplImage *kernel1=cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);
IplImage *kernel2=cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);
IplImage *kernel3=cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);
IplImage *kernel4=cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);
IplImage *bindetect=cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);
float a[25]={0,0,0,0,0,0,0,0,0,0,1,1,-4,1,1,0,0,0,0,0,0,0,0,0,0};
float b[25]={0,0,1,0,0,0,0,1,0,0,0,0,-4,0,0,0,0,1,0,0,0,0,1,0,0};
float c[25]={0,0,0,0,1,0,0,0,1,0,0,0,-4,0,0,0,1,0,0,0,1,0,0,0,0};
float d[25]={1,0,0,0,0,0,1,0,0,0,0,0,-4,0,0,0,0,0,1,0,0,0,0,0,1};
CvMat kernelA=cvMat(5,5,CV_32F,a);
CvMat kernelB=cvMat(5,5,CV_32F,b);
CvMat kernelC=cvMat(5,5,CV_32F,c);
CvMat kernelD=cvMat(5,5,CV_32F,d);
cvCvtColor(img,gray,CV_BGR2GRAY);
img=cvLoadImage("F:\\testData\\test1.BMP");
cvCvtColor(img,backgray,CV_BGR2GRAY);
cvNamedWindow("DIFFER",CV_WINDOW_AUTOSIZE);
cvNamedWindow("GRAY",CV_WINDOW_AUTOSIZE);
cvNamedWindow("BACKGROUD",CV_WINDOW_AUTOSIZE);
cvNamedWindow("EDGE",CV_WINDOW_AUTOSIZE);
cvNamedWindow("BINEDGE",CV_WINDOW_AUTOSIZE);
cvAbsDiff(gray,backgray,differgray);
cvThreshold(differgray,bindetect,20,255,CV_THRESH_BINARY);
cvSobel(differgray,edgegray,1,1,3);
//cvCanny(differgray,binedge,150,100,3);
cvConvertScale(edgegray, binedge, 1.0, 0.0);
cvThreshold(binedge,binedge,50,255,CV_THRESH_BINARY);
cvFilter2D(binedge,kernel1,&kernelA,cvPoint(-1,-1));
cvFilter2D(binedge,kernel2,&kernelB,cvPoint(-1,-1));
cvFilter2D(binedge,kernel3,&kernelC,cvPoint(-1,-1));
cvFilter2D(binedge,kernel4,&kernelD,cvPoint(-1,-1));
cvMax(kernel1,binedge,binedge);
cvMax(kernel2,binedge,binedge);
cvMax(kernel3,binedge,binedge);
cvMax(kernel4,binedge,binedge);
for (int i=0;i < gray->width;i++)
for (int j=0;j < gray->height;j++)
{
if (((uchar*)(bindetect->imageData+j*bindetect->widthStep))[i]==255&&((uchar*)(differgray->imageData+j*differgray->widthStep))[i]<80)
((uchar*)(bindetect->imageData+j*bindetect->widthStep))[i]=((uchar*)(binedge->imageData+j*binedge->widthStep))[i];
}
//cvErode(bindetect, bindetect, 0, 1);//“最小化”操作,亮的區域被隔離并且縮小
cvDilate(bindetect, bindetect, 0, 1);
cvShowImage("BACKGROUD",bindetect);
cvShowImage("DIFFER",differgray);
cvShowImage("GRAY",gray);
cvShowImage("EDGE",edgegray);
cvShowImage("BINEDGE",binedge);
cvWaitKey(0);
cvReleaseImage(&backgray);
cvReleaseImage(&gray);
cvReleaseImage(&differgray);
cvReleaseImage(&edgegray);
cvDestroyWindow("GRAY");
cvDestroyWindow("RGB");
cvDestroyWindow("DIFFER");
cvDestroyWindow("EDGE");
}
效果:
與背景內插補點圖
陰影抑制二值圖
參考文獻:
《基于視覺的交通違章停車檢測方法研究》 褚洪君 哈爾濱工業大學 2009 年 6 月