// hil.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include"cv.h"
#include"highgui.h"
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<windows.h>
#include<time.h>
using namespace cv;
using namespace std;
#define GMM_MAX_COMPONT 3
Mat w[GMM_MAX_COMPONT];
Mat u[GMM_MAX_COMPONT];
Mat sigma[GMM_MAX_COMPONT];
// Mat bg_bw[GMM_MAX_COMPONT]; //用来给高斯模型排序的量
Mat fit_num,gmask;
bool pause=false;
void main()
{
int M=3,sd_init=6,min_index=0;
double D=2.5,alph=0.01,thresh=0.25,p=alph/(1/GMM_MAX_COMPONT),temp;
int t=0;
int i,j,m;
int rank_ind[GMM_MAX_COMPONT],rank_ind_temp=0;
float rank[GMM_MAX_COMPONT],rank_temp=0.0;
clock_t start_time,finish_time;
float program_time;
// CvCapture* capture=cvCaptureFromCAM(0);
// CvCapture *capture=cvCreateFileCapture("d:\\xiaoqu.avi");
Mat frame,frame_gray,img,frg;
VideoCapture capture;
capture.open("d:\\xiaoqu.avi");
capture >> frame;
for(j=0;j<GMM_MAX_COMPONT;j++)
{
w[j]=Mat(frame.size(),CV_32FC1,0.0);
u[j]=Mat(frame.size(),CV_8UC1,-1); //为什么如果这个地方赋值为0就会出错??
sigma[j]=Mat(frame.size(),CV_32FC1,0.0);
}
for(i=0;i<frame.rows;i++)
for(j=0;j<frame.cols;j++)
for(m=0;m<GMM_MAX_COMPONT;m++)
{
u[m].at<unsigned char>(i,j)=frame.at<unsigned char>(i,j);
w[m].at<float>(i,j)=1.0/4;
sigma[m].at<float>(i,j)=sd_init;
}
while(1)
{
start_time=clock();
if (frame.empty())
break;
t=t+1;
cvtColor(frame, frame_gray, CV_RGB2GRAY);
imshow("1",frame_gray);
// system("pause");
img = frame_gray.clone();
frg = img.clone();
imshow("3",frg);
for(i=0;i<img.rows;i++){
for(j=0;j<img.cols;j++){
pause=false;
temp=0;
for(m=0;m<GMM_MAX_COMPONT;m++)
{
if((double)(abs(img.at<unsigned char>(i,j)-u[m].at<unsigned char>(i,j)))<D*sigma[m].at<float>(i,j))
{
pause=true;
w[m].at<float>(i,j)=(1-alph)*w[m].at<float>(i,j)+alph;
p=alph/w[m].at<float>(i,j);
u[m].at<unsigned char>(i,j)=(1-p)*u[m].at<unsigned char>(i,j)+p*img.at<unsigned char>(i,j);
sigma[m].at<float>(i,j)=sqrt((1-p)*(sigma[m].at<float>(i,j))*(sigma[m].at<float>(i,j))+p*(img.at<unsigned char>(i,j)-u[m].at<unsigned char>(i,j))*(img.at<unsigned char>(i,j)-u[m].at<unsigned char>(i,j)));
}else
w[m].at<float>(i,j)=(1-alph)*w[m].at<float>(i,j);
temp+=w[m].at<float>(i,j);
}
for(m=0;m<GMM_MAX_COMPONT;m++)
{
w[m].at<float>(i,j)=w[m].at<float>(i,j)/temp;
}
temp=w[0].at<float>(i,j);
for(m=0;m<GMM_MAX_COMPONT;m++)
{
if(w[m].at<float>(i,j)<=temp)
{
min_index=m;
temp=w[m].at<float>(i,j);
}
rank_ind[m]=m;
}
if(pause==false)
{
u[min_index].at<unsigned char>(i,j)=img.at<unsigned char>(i,j);
sigma[min_index].at<float>(i,j)=sd_init;
}
for(m=0;m<GMM_MAX_COMPONT;m++)
rank[m]=w[m].at<float>(i,j)/sigma[m].at<float>(i,j);
for(m=0;m<GMM_MAX_COMPONT;m++)
{
for(int k=0;k<m;k++)
{
if(rank[m]>rank[k])
{
rank_temp=rank[k];
rank[k]=rank[m];
rank[m]=rank_temp;
rank_ind_temp=rank_ind[k];
rank_ind[k]=rank_ind[m];
rank_ind[m]=rank_ind_temp;
}
}
}
pause=false;m=0;
// cout<<(int)img.at<unsigned char>(i,j)<<" "<<(int)u[rank_ind[m]].at<unsigned char>(i,j)<<endl;
// system("pause");
while((pause==false)&&(m<M))
{
if(w[rank_ind[m]].at<float>(i,j)>=thresh)
if(abs(img.at<unsigned char>(i,j)-u[rank_ind[m]].at<unsigned char>(i,j))<=D*sigma[rank_ind[m]].at<float>(i,j))
{
frg.at<unsigned char>(i,j)=0;
pause=true;
}
else
frg.at<unsigned char>(i,j)=255;
// cout<<(int)frg.at<unsigned char>(i,j)<<endl;
m++;
}
}
}
// Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
erode(frg, frg, 2);
// erode(frg, frg, element);
// dilate(frg, frg,element);
imshow("2",frg);
capture >> frame;
char c=cvWaitKey(33);
if(c==27)break;
finish_time=clock();
program_time=(float)(finish_time-start_time)/CLOCKS_PER_SEC;
printf("%f\n",program_time);
}
}