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, IPL_DEPTH_32F, 3);

IprevF = cvCreateImage(sz, IPL_DEPTH_32F, 3);

IhiF = cvCreateImage(sz, IPL_DEPTH_32F, 3);

IlowF = cvCreateImage(sz, IPL_DEPTH_32F, 3);

Ilow1 = cvCreateImage(sz, IPL_DEPTH_32F, 1);

Ilow2 = cvCreateImage(sz, IPL_DEPTH_32F, 1);

Ilow3 = cvCreateImage(sz, IPL_DEPTH_32F, 1);

Ihi1 = cvCreateImage(sz, IPL_DEPTH_32F, 1);

Ihi2 = cvCreateImage(sz, IPL_DEPTH_32F, 1);

Ihi3 = cvCreateImage(sz, IPL_DEPTH_32F, 1);

cvZero(IavgF);

cvZero(IdiffF);

cvZero(IprevF);

cvZero(IhiF);

cvZero(IlowF);

Icount = 0.00001;

Iscratch = cvCreateImage(sz, IPL_DEPTH_32F, 3);

Iscratch2 = cvCreateImage(sz, IPL_DEPTH_32F, 3);

Igray1 = cvCreateImage(sz, IPL_DEPTH_32F, 1);

Igray2 = cvCreateImage(sz, IPL_DEPTH_32F, 1);

Igray3 = cvCreateImage(sz, IPL_DEPTH_32F, 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, Iscratch, scale);

cvAdd(Iscratch, IavgF, IhiF);

cvSplit(IhiF, Ihi1, Ihi2, Ihi3, 0);

}

void setLowThreshold(float scale){

cvConvertScale(IdiffF, Iscratch, scale);

cvAdd(IavgF, Iscratch, IlowF);

cvSplit(IlowF,Ilow1,Ilow2,Ilow3, 0);

}

void createModelsfromStats(){

cvConvertScale(IavgF, 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, Iscratch, 1, 0);

cvSplit(Iscratch, Igray1, Igray2, Igray3, 0);

cvInRange(Igray1, Ilow1, Ihi1, Imask);

cvInRange(Igray2, Ilow2, Ihi2, Imaskt);

cvOr(Imask, Imaskt, Imask);

cvInRange(Igray3, Ilow3, Ihi3, Imaskt);

cvOr(Imask, Imaskt, 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, IPL_DEPTH_8U, 1);;

backgroundDiff(src_ipl, myImask);

cvSaveImage(newcontour, myImask);

}

DeallocateImages();

tm.stop();

cout << "count=" << tm.getCounter() << ",process time=" << tm.getTimeMilli() << endl;

}

然而对我的图还是不适合分割出轮廓:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 opencv平均背景法详解 的全部内容, 来源链接: utcz.com/p/245038.html

回到顶部