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