转自(http://blog.csdn.net/augusdi/article/details/8865499)
- // threeDifferent.cpp : 定义控制台应用程序的入口点。
- //
- #include "stdafx.h"
- #include "highgui.h"
- #include "cv.h"
- #include "cxcore.h"
- #include "cvaux.h"
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <algorithm>
- #include <queue>
- #include <vector>
- #include <windows.h>
- using namespace std;
- #define GET_IMAGE_DATA(img, x, y) ((uchar*)(img->imageData + img->widthStep * (y)))[x]
- int T = 10;
- int Num[300];
- int Sum[300];
- void InitPixel(IplImage * img, int &_low, int &_top)
- {
- memset(Num,0,sizeof(Num));
- memset(Sum,0,sizeof(Sum));
- _low = 255;
- _top = 0;
- for(int i = 0;i < img->height;i++)
- {
- for(int j = 0;j < img->width;j++)
- {
- int temp = ((uchar*)(img->imageData + img->widthStep*i))[j];
- if(temp < _low)
- _low = temp;
- if(temp > _top)
- _top = temp;
- Num[temp] += 1;
- }
- }
- for(int i = 1 ; i < 256 ; i++)
- {
- Sum[i] = Sum[i-1]+ i*Num[i];
- Num[i] += Num[i-1];
- }
- }
- int otsu (IplImage *img)
- {
- int _low,_top,mbest=0;
- float mn = img->height*img->width;
- InitPixel(img,_low,_top);
- float max_otsu = 0;
- mbest = 0;
- if( _low == _top)
- mbest = _low;
- else
- {
- for(int i = _low; i< _top ; i++)
- {
- float w0 = (float)((Num[_top]-Num[i]) / mn);
- float w1 = 1 - w0;
- float u0 = (float)((Sum[_top]-Sum[i])/(Num[_top]-Num[i]));
- float u1 = (float)(Sum[i]/Num[i]);
- float u = w0*u0 + w1*u1;
- float g = w0*(u0 - u)*(u0 - u) + w1*(u1 - u)*(u1 - u);
- if( g > max_otsu)
- {
- mbest = i;
- max_otsu = g;
- }
- }
- }
- return mbest;
- }
- int main()
- {
- int ncount=0;
- IplImage *image1=NULL;
- IplImage *image2=NULL;
- IplImage *image3=NULL;
- IplImage *Imask =NULL;
- IplImage *Imask1=NULL;
- IplImage *Imask2=NULL;
- IplImage *Imask3=NULL;
- IplImage *mframe=NULL;
- CvCapture *capture = cvCreateFileCapture("2.avi");
- //CvCapture *capture = cvCreateCameraCapture(0);
- cvNamedWindow("src");
- cvNamedWindow("dst");
- cvNamedWindow("Imask1");
- cvNamedWindow("Imask2");
- cvNamedWindow("Imask3");
- //cvCreateTrackbar("T","dst",&T,255,0);
- while(mframe=cvQueryFrame(capture))
- {
- DWORD start=GetTickCount();
- if(ncount>1000000000)
- ncount=100;
- ncount+=1;
- if(ncount==1)
- {
- image1=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
- image2=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
- image3=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
- Imask =cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
- Imask1=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
- Imask2=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
- Imask3=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
- cvCvtColor(mframe,image1,CV_BGR2GRAY);
- }
- if(ncount==2)
- cvCvtColor(mframe,image2,CV_BGR2GRAY);
- if(ncount>=3)
- {
- if(ncount==3)
- cvCvtColor(mframe,image3,CV_BGR2GRAY);
- else
- {
- cvCopy(image2,image1);
- cvCopy(image3,image2);
- cvCvtColor(mframe,image3,CV_BGR2GRAY);
- }
- cvAbsDiff(image2,image1,Imask1);
- cvAbsDiff(image3,image2,Imask2);
- //cvShowImage("Imask1",Imask1);
- //cvShowImage("Imask2",Imask2);
- int mbest1 = otsu(Imask1);
- cvSmooth(Imask1, Imask1, CV_MEDIAN);
- cvThreshold(Imask1,Imask1,/*mbest1*/10, 255, CV_THRESH_BINARY);
- int mbest2 = otsu(Imask2);
- cvSmooth(Imask2,Imask2, CV_MEDIAN);
- cvThreshold(Imask2,Imask2,/*mbest2*/10, 255, CV_THRESH_BINARY);
- // cout<<mbest1<<" "<<mbest2<<endl;
- cvAnd(Imask1,Imask2,Imask);
- // cvErode(Imask, Imask);
- // cvDilate(Imask,Imask);
- DWORD finish=GetTickCount();
- // cout<<finish-start<<"ms"<<endl;
- cvShowImage("src",image2);
- cvShowImage("dst",Imask);
- }
- char c = cvWaitKey(30);
- if(c==27)
- break;
- }
- return 0;
- }