博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
阴影消除研究
阅读量:317 次
发布时间:2019-03-03

本文共 15711 字,大约阅读时间需要 52 分钟。

用GMM提取运动目标,在光照比较强烈的条件下,会把阴影也当成运动目标提取出来。 利用阴影亮度降低而色度基本不变的特点,在HSV空间里利用以下公式进行判断

这里写图片描述

这里写图片描述

#include "stdafx.h"#include "cv.h"#include "highgui.h"#include 
#include "HaarDetect.h"#include "io.h"#include "direct.h" /*mkdir("E:\mydir");*/#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef _EiC#define WIN32#endif// shade1.cpp : Defines the entry point for the console application.//// shade.cpp : Defines the entry point for the console application.////视频检测//#include "stdafx.h"#include "stdio.h"#include
#include "cv.h"#include "highgui.h"#include "math.h"//#pragma comment( lib, "cv200.lib" )//#pragma comment( lib, "cxcore200.lib" )//#pragma comment( lib, "highgui200.lib" )//#pragma comment( lib, "cvaux200.lib" )/*void labeling(IplImage *src,IplImage* dst){ CvMemStorage* storage=0; storage = cvCreateMemStorage(0); CvSeq* contour = 0; cvCopy(src,dst,0); cvFindContours(dst,storage,&contour,sizeof(CvContour), CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE); int num = 0; for (;contour!=0;contour=contour->h_next) { CvRect rect; rect = cvBoundingRect(contour,0); num++; if (rect.height + rect.width>=50) { cvRectangle(src,cvPoint(rect.x,rect.y),cvPoint(rect.x+rect.width,rect.y+rect.height), CV_RGB(255,255,255),1,8); } }}*/void ShadeDetect(IplImage *currImg, IplImage *bkImg/*, IplImage *shdadeImg*//*,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
imageData+i*currImg->widthStep; // bkData=(unsigned char*)bkImg->imageData+i*bkImg->widthStep; // shadeData=(unsigned char*)shdadeImg->imageData+i*shdadeImg->widthStep; // for (j=0;j
Gt?Gt:Rt)>Bt?Bt:(Rt>Gt?Gt:Rt); // rt=acos((0.5*((Rt-Gt)+(Rt-Bt)))/(sqrt((Rt-Gt)*(Rt-Gt)+(Rt-Bt)*(Rt-Gt)))); // gt=1-3*tf/(Rt+Gt+Bt); // It=(Rt+Gt+Bt)/3; // // Bk normalized // Rb=bkData[j*3]; // Gb=bkData[j*3+1]; // Bb=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]=0; // } // } //}}int main(int argc, char* argv[]){ //声明IplImage指针 IplImage* pFrame = NULL; IplImage* pFrame18 = NULL; IplImage* Iavg = NULL; IplImage* pBkImg = NULL; IplImage* pFrImg = NULL; int avg1[240][320]={ 0}; int avg2[240][320]={ 0}; int avg3[240][320]={ 0}; ///////////////////////////////////////////////////////////////////////////////////////////// IplImage* pRetImg = NULL; IplImage* pFkHsv = NULL; //IplImage* pFrImg = NULL; IplImage* pFrImgGray = NULL; IplImage* pFrImgR = NULL; IplImage* pFrImgG = NULL; IplImage* pFrImgB = NULL; IplImage* pBkHsv = NULL; //IplImage* pBkImg = NULL; IplImage* pBkImgR = NULL; IplImage* pBkImgG = NULL; IplImage* pBkImgB = NULL; //IplImage* pBkImg1 = NULL; //IplImage* shadeImg = NULL; //IplImage* dst=NULL; CvMat* pFrameMatGray = NULL; CvMat* pFrameMatR = NULL; CvMat* pFrameMatG = NULL; CvMat* pFrameMatB = NULL; CvMat* pFrMatGray = NULL; CvMat* pFrMatR = NULL; CvMat* pFrMatG = NULL; CvMat* pFrMatB = NULL; CvMat* pBkMatGray = NULL; CvMat* pBkMatR = NULL; CvMat* pBkMatG = NULL; CvMat* pBkMatB = NULL; //void labeling(IplImage *src,IplImage* dst); //CvMat* pBkMattmp = NULL; CvCapture* pCapture = NULL; double nFrmNum = 0.; //创建窗口 cvNamedWindow("video", 1); cvNamedWindow("background",1); cvNamedWindow("foreground0",1); cvNamedWindow("foreground",1); //cvNamedWindow("shade", 1); //使窗口有序排列 cvMoveWindow("video", 30, 0); cvMoveWindow("background", 360, 120); cvMoveWindow("foreground", 690, 240); if( !(pCapture = cvCreateFileCapture("E:\\video\\高速公路 汽车阴影.AVI"))) { printf("不能打开视频文件!\n"); return -1; } pFrame18 = cvQueryFrame( pCapture ); pFrame = cvQueryFrame( pCapture ); CvSize sz=cvGetSize(pFrame); Iavg=cvCreateImage(cvGetSize(pFrame),IPL_DEPTH_16U,3); //int step = pFrame->widthStep/sizeof(uchar); // for (int i=0;i
height;i++) // { // for (int j=0;j
width;j++) // { // Iavg->imageData[i*step+j*3+0]=0; // Iavg->imageData[i*step+j*3+1]=0; // Iavg->imageData[i*step+j*3+2]=0; // } // } pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,3); pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,3); pRetImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,3); pBkHsv = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,3);// pFkHsv = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,3); //double* avg=(double*)malloc((pFrame->width*pFrame->height)*sizeof(double));uchar* data=(uchar *)pFrame->imageData; int step = pFrame->widthStep/sizeof(uchar); int channels = pFrame->nChannels; //逐帧读取视频 while(nFrmNum<=100)//获取视频帧,到结尾退出循环 { pFrame = cvQueryFrame( pCapture ); nFrmNum++; //char* s11=(char *)malloc(sizeof(char)*255);// //strcpy(s11,"E:\\"); //strcat(s11,"\\"); //char s3[100]; //itoa(nFrmNum,s3,10); /*把a转到s中,10是十进制*/ //strcat(s11,s3); //strcat(s11,".jpg"); //cvSaveImage(s11,pFrame);//保存图片 //free(s11);// /*cvShowImage("pFrame", pFrame); cvWaitKey(10);*/ //如果是第一帧,需要申请内存,并初始化// if(nFrmNum == 1)// { ///////////////////////////////////////////////////////////////////////////////////////// pBkImgGray = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);// pFrImgGray = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);//// pBkMatGray = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);// pFrMatGray = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);// pFrameMatGray = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);// //转化成单通道图像再处理// cvCvtColor(pFrame, pBkImgGray, CV_BGR2GRAY);// cvCvtColor(pFrame, pFrImgGray, CV_BGR2GRAY);//// cvConvertScale(pFrImgGray, pFrameMatGray);// cvConvertScale(pFrImgGray, pFrMatGray);// cvConvertScale(pFrImgGray, pBkMatGray);///////////////////////////////////////////////////////////////////////////////////////// // pRetImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,3);//// // pBkImgR = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);// pBkImgG = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);// pBkImgB = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);//// pFkHsv = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,3);//// pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,3);//// pFrImgR = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);// pFrImgG = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);// pFrImgB = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);//// //pBkImg1 = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,3);// //shadeImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);// // pBkMatR = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);// pBkMatG = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);// pBkMatB = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);// //pBkMattmp = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);// // pFrMatR = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);// pFrMatG = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);// pFrMatB = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);//// pFrameMatR = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);// pFrameMatG = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);// pFrameMatB = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);//// //转化成单通道图像再处理// cvSplit(pFrame, pBkImgB, pBkImgG, pBkImgR, 0);//分离RGB通道,分别得到BGR的单通道图像// //cvCvtColor(pFrame, pBkImg, CV_BGR2GRAY);// cvSplit(pFrame, pFrImgB, pFrImgG, pFrImgR, 0);//分离RGB通道,分别得到BGR的单通道图像// //cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);//// cvConvertScale(pFrImgR, pFrameMatR);// cvConvertScale(pFrImgG, pFrameMatG);// cvConvertScale(pFrImgB, pFrameMatB);//// cvConvertScale(pFrImgR, pBkMatR);// cvConvertScale(pFrImgG, pBkMatG);// cvConvertScale(pFrImgB, pBkMatB);//// cvConvertScale(pFrImgR, pFrMatR);// cvConvertScale(pFrImgG, pFrMatG);// cvConvertScale(pFrImgB, pFrMatB);//// //cvCopy(pFrame,pBkImg1,NULL);// //cvConvertScale(pFrImg, pBkMattmp);////// }// else// { // cvCvtColor(pFrame, pFrImgGray, CV_BGR2GRAY);// cvConvertScale(pFrImgGray, pFrameMatGray);// //高斯滤波先,以平滑图像// cvSmooth(pFrameMatGray, pFrameMatGray, CV_GAUSSIAN, 3, 0, 0);//// //当前帧跟背景图相减// cvAbsDiff(pFrameMatGray, pBkMatGray, pFrMatGray);//// //二值化前景图// cvThreshold(pFrMatGray, pFrImgGray, 60, 255.0, CV_THRESH_BINARY);//// //进行形态学滤波,去掉噪音 // /*cvErode(pFrImgGray, pFrImgGray, 0, 1);// cvDilate(pFrImgGray, pFrImgGray, 0, 1);*///// //更新背景// cvRunningAvg(pFrameMatGray, pBkMatGray, 0.003, 0);// //将背景转化为图像格式,用以显示// cvConvertScale(pBkMatGray, pBkImgGray);//// //显示图像// //cvShowImage("pFrame", pFrame);// cvShowImage("pBkImgGray", pBkImgGray);// cvShowImage("pFrImgGray", pFrImgGray);// // //更新背景// cvRunningAvg(pFrameMatGray, pBkMatGray, 0.003, 0);// //将背景转化为图像格式,用以显示// cvConvertScale(pBkMatGray, pBkImgGray);// //////////////////////////////////////////////////////////////////////////////////////////////// cvSplit(pFrame, pFrImgB, pFrImgG, pFrImgR, 0);//分离RGB通道,分别得到BGR的单通道图像// //cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);// // //cvCvtColor(pFrame, pFrImg, CV_BGR2HSV);// cvConvertScale(pFrImgR, pFrameMatR);// cvConvertScale(pFrImgG, pFrameMatG);// cvConvertScale(pFrImgB, pFrameMatB);//// //当前帧跟背景图相减// cvAbsDiff(pFrameMatR, pBkMatR, pFrMatR);// cvAbsDiff(pFrameMatG, pBkMatG, pFrMatG);// cvAbsDiff(pFrameMatB, pBkMatB, pFrMatB);//// //cvAbsDiff(pBkMat, pFrMat, pBkMattmp);//背景相消,需要足够多帧// //cvOr(pBkMat, pBkMattmp, pBkMat);// //高斯滤波先,以平滑图像// //cvFlip(pFrMat,NULL,0);// cvSmooth(pFrMatR, pFrMatR, CV_GAUSSIAN, 3,0,0);// cvSmooth(pFrMatG, pFrMatG, CV_GAUSSIAN, 3,0,0);// cvSmooth(pFrMatB, pFrMatB, CV_GAUSSIAN, 3,0,0);//// cvConvertScale(pFrMatR, pFrImgR);// cvConvertScale(pFrMatG, pFrImgG);// cvConvertScale(pFrMatB, pFrImgB);// //二值化前景图// //cvSmooth(pFrImg, pFrImg, CV_MEDIAN, 3,0,0);// /*cvThreshold(pFrMatR, pFrImgR, 30, 255, CV_THRESH_BINARY);// cvThreshold(pFrMatG, pFrImgG, 30, 255, CV_THRESH_BINARY);// cvThreshold(pFrMatB, pFrImgB, 30, 255, CV_THRESH_BINARY);*///// //进行形态学滤波,去掉噪音// // cvErode(pFrImgR, pFrImgR, 0, 1);//腐蚀// //cvErode(pFrImgG, pFrImgG, 0, 1);//腐蚀// //cvErode(pFrImgB, pFrImgB, 0, 1);//腐蚀//// // cvDilate(pFrImgR, pFrImgR, 0, 1);//膨胀// //cvDilate(pFrImgG, pFrImgG, 0, 1);//膨胀// //cvDilate(pFrImgB, pFrImgB, 0, 1);//膨胀//// //更新背景// // //运动平滑(alpha参数:以多快的速度忘掉前面的帧)// cvRunningAvg(pFrameMatR, pBkMatR, 0.003, 0);//0.005// cvRunningAvg(pFrameMatG, pBkMatG, 0.003, 0);// cvRunningAvg(pFrameMatB, pBkMatB, 0.003, 0);// //将背景转化为图像格式,用以显示// // cvConvertScale(pBkMatR, pBkImgR);// cvConvertScale(pBkMatG, pBkImgG);// cvConvertScale(pBkMatB, pBkImgB);// //cvConvertScale(pBkMat, pBkImg);// //cvCvtColor(pBkImg, pBkImg1, CV_GRAY2BGR);// //ShadeDetect(pFrame,pBkImg1,shadeImg,0.3,0.8,0.9,1);// //显示图像// //cvFlip(shadeImg,NULL,0);// // //cvFlip(pBkImg,NULL,0);// //cvCopy(dst,pFrImg,0);// // cvMerge(pFrImgB, pFrImgG, pFrImgR, 0, pFrImg);//逆运算,将三通道图像融合得到彩色图像// cvSaveImage("E:\\pFrImg.jpg",pFrImg);//保存图片// cvCvtColor(pFrImg,pFkHsv,CV_BGR2HSV);//得到HSV图// cvShowImage("foreground0", pFrImg);//// //cvAnd(pFrImg,shadeImg,pFrImg,NULL);// //labeling(pFrImg,pFrImg);// //cvErode(pFrImg, pFrImg, 0, 1);//腐蚀// //cvDilate(pFrImg, pFrImg, 0, 1);//膨胀// // //cvShowImage("shade", shadeImg);// //cvShowImage("video", pFrame);//// cvMerge(pBkImgB, pBkImgG, pBkImgR, 0, pBkImg);//逆运算,将三通道图像融合得到彩色图像// cvSaveImage("E:\\pBkImg.jpg",pBkImg);//保存图片// cvCvtColor(pBkImg,pBkHsv,CV_BGR2HSV);//得到HSV图// cvShowImage("background", pBkImg);// //cvShowImage("foreground", pFrImg);// //如果有按键事件,则跳出循环// //此等待也为cvShowImage函数提供时间完成显示// //等待时间可以根据CPU速度调整// if( cvWaitKey(50)>= 0)// break; ///////////////<<<<<<
height;i++) { for (int j=0;j
width;j++) { avg1[i][j]+=data[i*step+j*channels+0]; avg2[i][j]+=data[i*step+j*channels+1]; avg3[i][j]+=data[i*step+j*channels+2]; /*Iavg->imageData[i*step+j*3+0]+=pFrame->imageData[i*step+j*3+0]; Iavg->imageData[i*step+j*3+1]+=pFrame->imageData[i*step+j*3+1]; Iavg->imageData[i*step+j*3+2]+=pFrame->imageData[i*step+j*3+2]; */ } } //cvShowImage("pRetImg", pRetImg); ///////////////>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //ShadeDetect(pFkHsv,pBkHsv); } nFrmNum--; int step2 = pFrame->widthStep/sizeof(uchar); for (int i=0;i
height;i++) { for (int j=0;j
width;j++) { pBkImg->imageData[i*step2+j*3+0]=(uchar)(avg1[i][j]/nFrmNum); pBkImg->imageData[i*step2+j*3+1]=(uchar)(avg2[i][j]/nFrmNum); pBkImg->imageData[i*step2+j*3+2]=(uchar)(avg3[i][j]/nFrmNum); } } cvShowImage("pBkImg", pBkImg); //cvConvertScale(Iavg, pFrameMatGray); //cvShowImage("pFrameMatGray", pFrameMatGray); //等待时间可以根据CPU速度调整 cvWaitKey(50); pFrame18 = cvLoadImage( "E:\\16.jpg", 1); cvShowImage("pFrame18", pFrame18); cvWaitKey(50); data=(uchar *)pFrame18->imageData; step = pFrame18->widthStep/sizeof(uchar); channels = pFrame18->nChannels; uchar* data2=(uchar *)pBkImg->imageData; uchar* data3=(uchar *)pFrImg->imageData; for (int i=0;i
height;i++) { for (int j=0;j
width;j++) { /*data3[i*step+j*channels+0]= ((abs(data[i*step+j*channels+0]-data2[i*step+j*channels+0])>=20) ? data[i*step+j*channels+0]:0); data3[i*step+j*channels+1]= ((abs(data[i*step+j*channels+1]-data2[i*step+j*channels+1])>=20) ? data[i*step+j*channels+1]:0); data3[i*step+j*channels+2]= ((abs(data[i*step+j*channels+2]-data2[i*step+j*channels+2])>=20) ? data[i*step+j*channels+2]:0);*/ if((abs(data[i*step+j*channels+0]-data2[i*step+j*channels+0])>=40)|| (abs(data[i*step+j*channels+1]-data2[i*step+j*channels+1])>=40)|| (abs(data[i*step+j*channels+2]-data2[i*step+j*channels+2])>=40)) { data3[i*step+j*channels+0]=data[i*step+j*channels+0]; data3[i*step+j*channels+1]=data[i*step+j*channels+1]; data3[i*step+j*channels+2]=data[i*step+j*channels+2]; } else { data3[i*step+j*channels+0]=0; data3[i*step+j*channels+1]=0; data3[i*step+j*channels+2]=0; } } } cvShowImage("pFrImg", pFrImg); cvWaitKey(50); /////////////////////////////////////////////////////////////////////////////////////////////////////// cvCvtColor(pBkImg, pBkHsv, CV_BGR2HSV); cvCvtColor(pFrImg, pFkHsv, CV_BGR2HSV); cvShowImage("pFkHsv", pFkHsv); cvWaitKey(50); step = pRetImg->widthStep/sizeof(uchar); double a,b,c,d;for (int i=0;i
height;i++){ for (int j=0;j
width;j++) { a=(double)(pFkHsv->imageData[i*step+j*3+2])/(pBkHsv->imageData[i*step+j*3+2]); b=(double)(pFkHsv->imageData[i*step+j*3+2])/(pBkHsv->imageData[i*step+j*3+2]); c=abs(pFkHsv->imageData[i*step+j*3+1]-pBkHsv->imageData[i*step+j*3+1]); d=abs(pFkHsv->imageData[i*step+j*3+0]-pBkHsv->imageData[i*step+j*3+0]); if ( (a<=0.35)&&(b>=0.05)&& (c<=4*255)&&(d<=1*255) ) { pRetImg->imageData[i*step+j*3+0]=255; pRetImg->imageData[i*step+j*3+1]=255; pRetImg->imageData[i*step+j*3+2]=255; } else { pRetImg->imageData[i*step+j*3+0]=0; pRetImg->imageData[i*step+j*3+1]=0; pRetImg->imageData[i*step+j*3+2]=0; } }} cvShowImage("pRetImg", pRetImg); //等待时间可以根据CPU速度调整 cvWaitKey(50); //销毁窗口 cvDestroyWindow("video"); cvDestroyWindow("background"); cvDestroyWindow("foreground0"); cvDestroyWindow("foreground"); //cvReleaseImage(&shadeImg); cvDestroyWindow("shade"); //释放图像和矩阵 cvReleaseImage(&pFrImg); cvReleaseImage(&pBkImg); //cvReleaseImage(&pBkImg1); /*cvReleaseMat(&pFrameMat); cvReleaseMat(&pFrMat); cvReleaseMat(&pBkMat);*/ cvReleaseCapture(&pCapture); return 0;}
你可能感兴趣的文章