1. 程式人生 > 程式設計 >opencv平均背景法詳解

opencv平均背景法詳解

本文例項為大家分享了opencv平均背景法的具體程式碼,供大家參考,具體內容如下

#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
IplImage *IavgF,*IdiffF,*IprevF,*IhiF,*IlowF;
IplImage *Iscratch,*Iscratch2;
IplImage *Igray1,*Igray2,*Igray3;
IplImage *Ilow1,*Ilow2,*Ilow3;
IplImage *Ihi1,*Ihi2,*Ihi3;
IplImage *Imaskt;
float Icount;
void AllocateImages(IplImage* I){
 CvSize sz = cvGetSize(I);
 IavgF = cvCreateImage(sz,IPL_DEPTH_32F,3);
 IdiffF = cvCreateImage(sz,3);
 IprevF = cvCreateImage(sz,3);
 IhiF = cvCreateImage(sz,3);
 IlowF = cvCreateImage(sz,3);
 Ilow1 = cvCreateImage(sz,1);
 Ilow2 = cvCreateImage(sz,1);
 Ilow3 = cvCreateImage(sz,1);
 Ihi1 = cvCreateImage(sz,1);
 Ihi2 = cvCreateImage(sz,1);
 Ihi3 = cvCreateImage(sz,1);
 cvZero(IavgF);
 cvZero(IdiffF);
 cvZero(IprevF);
 cvZero(IhiF);
 cvZero(IlowF);
 Icount = 0.00001;
 Iscratch = cvCreateImage(sz,3);
 Iscratch2 = cvCreateImage(sz,3);
 Igray1 = cvCreateImage(sz,1);
 Igray2 = cvCreateImage(sz,1);
 Igray3 = cvCreateImage(sz,1);
 Imaskt = cvCreateImage(sz,IPL_DEPTH_8U,1);
 cvZero(Iscratch);
 cvZero(Iscratch2);
}
void accumulateBackground(IplImage *I){
 static int first = 1;
 cvCvtScale(I,Iscratch,1,0);
 if (!first){
 cvAcc(Iscratch,IavgF);
 cvAbsDiff(Iscratch,IprevF,Iscratch2);
 cvAcc(Iscratch2,IdiffF);
 Icount += 1.0;
 }
 first = 0;
 cvCopy(Iscratch,IprevF);
}
void setHighThreshold(float scale){
 cvConvertScale(IdiffF,scale);
 cvAdd(Iscratch,IavgF,IhiF);
 cvSplit(IhiF,Ihi1,Ihi2,Ihi3,0);
}
void setLowThreshold(float scale){
 cvConvertScale(IdiffF,scale);
 cvAdd(IavgF,IlowF);
 cvSplit(IlowF,Ilow1,Ilow2,Ilow3,0);
}
 
void createModelsfromStats(){
 cvConvertScale(IavgF,(double)(1.0 / Icount));
 cvConvertScale(IdiffF,IdiffF,(double)(1.0 / Icount));
 cvAddS(IdiffF,cvScalar(1.0,1.0,1.0),IdiffF);
 setHighThreshold(10.0);
 setLowThreshold(4.0);
}
void backgroundDiff(IplImage* I,IplImage* Imask){
 cvCvtScale(I,0);
 cvSplit(Iscratch,Igray1,Igray2,Igray3,0);
 cvInRange(Igray1,Imask);
 cvInRange(Igray2,Imaskt);
 cvOr(Imask,Imaskt,Imask);
 cvInRange(Igray3,Imask);
 cvSubRS(Imask,Scalar(255),Imask);
}
void DeallocateImages(){
 cvReleaseImage(&IavgF);
 cvReleaseImage(&IdiffF);
 cvReleaseImage(&IprevF);
 cvReleaseImage(&IhiF);
 cvReleaseImage(&IlowF);
 cvReleaseImage(&Ilow1);
 cvReleaseImage(&Ilow2);
 cvReleaseImage(&Ilow3);
 cvReleaseImage(&Ihi1);
 cvReleaseImage(&Ihi2);
 cvReleaseImage(&Ihi3);
 cvReleaseImage(&Iscratch);
 cvReleaseImage(&Iscratch2);
 cvReleaseImage(&Igray1);
 cvReleaseImage(&Igray2);
 cvReleaseImage(&Igray3);
 cvReleaseImage(&Imaskt);
}
 
char filename[100];
char newcontour[100];
void main()
{
 TickMeter tm;
 tm.start();
 //many imgs
 IplImage* src = cvLoadImage("待處理背面圖\\55124.bmp");
 AllocateImages(src);
 for (int i = 55124; i <= 56460; i++)
 {
 sprintf(filename,"待處理背面圖\\%d.bmp",i);
 sprintf(newcontour,"分割前景\\%d.bmp",i);
 IplImage* src_ipl = cvLoadImage(filename);
 accumulateBackground(src_ipl);
 createModelsfromStats();
 CvSize sz = cvGetSize(src_ipl);
 IplImage* myImask = cvCreateImage(sz,1);;
 backgroundDiff(src_ipl,myImask);
 cvSaveImage(newcontour,myImask);
 }
 DeallocateImages();
 tm.stop();
 cout << "count=" << tm.getCounter() << ",process time=" << tm.getTimeMilli() << endl;
}

然而對我的圖還是不適合分割出輪廓:

opencv平均背景法詳解

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。