1、背景建模练习练习二帧差法:#include #include #include #define threshold_diff 20 /设置简单帧差法阈值using namespace cv;using namespace std;int main(int argc, unsigned char* argv) Mat img_src1, img_src2, img_dst, gray1, gray2, gray_diff; bool pause = false; VideoCapture vido_file(test.avi);/在这里改相应的文件名 namedWindow(foreground
2、, 0); for (;) if (!pause) vido_file img_src1; /提取一副图像 cvtColor(img_src1, gray1, CV_BGR2GRAY);/转化为灰度图像 imshow(video_src1, img_src1); waitKey(5); vido_file img_src2; /过5毫秒又一副图像 cvtColor(img_src2, gray2, CV_BGR2GRAY); imshow(video_src2, img_src2); waitKey(5); subtract(gray1, gray2, gray_diff); /函数计算两幅灰
3、度图像的差值 for (int i = 0; igray_diff.rows; i+) for (int j = 0; jgray_diff.cols; j+)/对于整个图像中的每个点如果差值大于阀值则把该点设为白色,否则设为黑色 if (abs(gray_diff.at(i, j) = threshold_diff) gray_diff.at(i, j) = 255; else gray_diff.at(i, j) = 0; imshow(foreground, gray_diff); /完成对每个点的检测后显示这幅图 char c = (char)waitKey(10); if (c =
4、27) break; if (c = ) pause = !pause; return 0;三帧差法:#include#include#include#define threshold_diff1 10#define threshold_diff2 10using namespace cv;using namespace std;int main(int argc, unsigned char* argv) Mat img_src1, img_src2, img_src3; Mat img_dst, gray1, gray2, gray3; Mat gray_diff1, gray_diff2
5、; Mat gray; bool pause = false; VideoCapture vido_file(test.avi); for (;) if (!pause) vido_file img_src1; cvtColor(img_src1, gray1, CV_BGR2GRAY); waitKey(5); vido_file img_src2; cvtColor(img_src2, gray2, CV_BGR2GRAY); waitKey(5); vido_file img_src3; cvtColor(img_src3, gray3, CV_BGR2GRAY); subtract(g
6、ray2, gray1, gray_diff1); subtract(gray3, gray2, gray_diff2);imshow(1, img_src2); imshow(2,gray1 ); imshow(3,gray2 ); imshow(4,gray_diff1 ); imshow(5,gray_diff2 ); for (int i = 0; i gray_diff1.rows; i+) for (int j = 0; j gray_diff1.cols; j+) if (abs(gray_diff1.at(i, j)threshold_diff1) gray_diff1.at(
7、i, j) = 255; else gray_diff1.at(i, j) = 0; if (abs(gray_diff2.at(i, j)threshold_diff2) gray_diff2.at(i, j) = 255; else gray_diff2.at(i, j) = 0; bitwise_and(gray_diff1, gray_diff2, gray);/求两个的交集 imshow(前景, gray); char c = (char)waitKey(500); if (c = 27)break; if (c = )pause = !pause; return 0;结果截图:平均
8、背景建模:通过多幅图像求图像的平均值和差值的平均值,并以此为依据建立背景模型,差值用于比较的阀值的参考数据,通过比较当前帧与背景模型,确定前景。#include #include #include IplImage *IavgF, *IdiffF, *IprevF, *IhiF, *IlowF;IplImage *Iscratch, *Iscratch2;IplImage * Igray1, *Igray2, *Igray3;IplImage *Ilow1, *Ilow2, *Ilow3;IplImage *Ihi1, *Ihi2, *Ihi3;IplImage *Imaskt;IplImag
9、e *Imask;float Icount;void AllocateImages(IplImage *I);void accumulateBackground(IplImage * I);void createModelsfromStats();void setHighThreshold(float scale);void setLowThreshold(float scale);void backgroundDiff(IplImage *I, IplImage * Imask);void DeallocateImages();int main(int argc, char * argv)
10、CvCapture *capture = cvCreateCameraCapture(-1); if (NULL = capture) printf(没有找到摄像头装置!n); return -1; IplImage * Img = cvQueryFrame(capture); cvNamedWindow(原图, 0); cvNamedWindow(检测图, 0); cvShowImage(原图, Img); AllocateImages(Img);/初始化 printf(开始统计背景模型n); while (Icount30)/统计背景模型 accumulateBackground(Img)
11、; Img = cvQueryFrame(capture); cvWaitKey(10); cvShowImage(原图, Img); printf(.); createModelsfromStats();/就算每一个像素的均值和方差观测 printf(n统计背景模型结束.n); printf(按任意键开始分割图像.n); cvWaitKey(NULL); printf(开始分割图像.n); while (1) Img = cvQueryFrame(capture); backgroundDiff(Img, Imask); cvShowImage(原图, Img); cvShowImage(检
12、测图, Imask); if (27 = cvWaitKey(100) break; cvDestroyAllWindows(); /释放内存 DeallocateImages(); cvReleaseCapture(&capture); return 0;/初始化函数:void AllocateImages(IplImage *I) /传入原图的大小,根据这个大小初始化。 CvSize sz = cvGetSize(I); IavgF = cvCreateImage(sz, IPL_DEPTH_32F, 3); IdiffF = cvCreateImage(sz, IPL_DEPTH_32F
13、, 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,
14、 IPL_DEPTH_32F, 1); Ihi2 = cvCreateImage(sz, IPL_DEPTH_32F, 1); Ihi3 = cvCreateImage(sz, IPL_DEPTH_32F, 1); cvZero(IavgF); /cvZero的作用是把矩阵里的值都置为零,初始化的作用。 cvZero(IdiffF); cvZero(IprevF); cvZero(IhiF); cvZero(IlowF); Icount = 0.00001; Iscratch = cvCreateImage(sz, IPL_DEPTH_32F, 3); Iscratch2 = cvCreate
15、Image(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); Imask = cvCreateImage(sz, IPL_DEPTH_8U, 1); cvZero(Iscratch); cvZero(Iscratch2); cvZero(
16、Imask); cvZero(Imaskt);/循环统计背景模型void accumulateBackground(IplImage * I) static int first = 1; cvCvtScale(I, Iscratch, 1, 0); /数组线性转化函数,四个参数分别为:转换前数组、转换后数组、转换比例因子、比例缩放后加到结果数组上的数。 if (!first) cvAcc(Iscratch, IavgF); /将帧叠加到累加器中三个参数:第一个是输入图像,第二个是图像的累积,第三个是可选择的运算。 cvAbsDiff(Iscratch, IprevF, Iscratch2);
17、/计算两个数组差的绝对值的函数,差的绝对值的结果为第三个参数。这里表示计算当前图像和上一个图像的差值。 cvAcc(Iscratch2, IdiffF); /IdiffF是相邻两幅图像差值的绝对值的累积 Icount += 1.0; first = 0; cvCopy(Iscratch, IprevF); /把第一个数组copy给第二个数组void createModelsfromStats() /通过除以输入图像积累的数目计算平均原始图像和绝对差分图像 cvConvertScale(IavgF, IavgF, (double)(1.0 / Icount); /通过多幅图像的积累除以图像的个数
18、得到平均原始图像。 cvConvertScale(IdiffF, IdiffF, (double)(1.0 / Icount); /相邻图像差值绝对值的平均值 /make sure diff is slways something cvAddS(IdiffF, cvScalar(1.0, 1.0, 1.0), IdiffF);/确保平均差分图像的值最小是1,第一个数组和第二个标量元素级相加得到第三个元素。 setHighThreshold(7.0);/当计算前景和背景阈值以及避免前景阈值和背景阈值相等而出现的退化情况时,我们要缩放这个因素 setLowThreshold(6.0);void s
19、etHighThreshold(float scale) cvConvertScale(IdiffF, Iscratch, scale); cvAdd(Iscratch, IavgF, IhiF); cvSplit(IhiF, Ihi1, Ihi2, Ihi3, 0); /把第一个多通道图像分为多个单通道图像void setLowThreshold(float scale) cvConvertScale(IdiffF, Iscratch, scale); cvSub(IavgF, Iscratch, IlowF); /矩阵减法运算 cvSplit(IlowF, Ilow1, Ilow2, Il
20、ow3, 0);void backgroundDiff(IplImage *I, IplImage * Imask) cvConvertScale(I, Iscratch, 1, 0); cvSplit(Iscratch, Igray1, Igray2, Igray3, 0); cvInRange(Igray1, Ilow1, Ihi1, Imask); /cvInRange的作用是判断第一个数组每个参数是不是在第二三个数组对应参数之间,把结果放入第四个参数的相对位置。 cvInRange(Igray2, Ilow2, Ihi2, Imaskt); cvOr(Imask, Imaskt, Im
21、ask); /求第一二个数组的并集,结果放入第三个数组中 cvInRange(Igray3, Ilow3, Ihi3, Imask); cvOr(Imask, Imaskt, Imask); cvSubRS(Imask, cvScalar(255), Imask);void DeallocateImages() cvReleaseImage(&IavgF); cvReleaseImage(&IdiffF); cvReleaseImage(&IprevF); cvReleaseImage(&IhiF); cvReleaseImage(&IlowF); cvReleaseImage(&Ilow1)
22、; cvReleaseImage(&Ilow2); cvReleaseImage(&Ilow3); cvReleaseImage(&Ihi1); cvReleaseImage(&Ihi2); cvReleaseImage(&Ihi3); cvReleaseImage(&Iscratch); cvReleaseImage(&Iscratch2); cvReleaseImage(&Igray1); cvReleaseImage(&Igray2); cvReleaseImage(&Igray3); cvReleaseImage(&Imaskt); cvReleaseImage(&Imask);均值漂
23、移算法:寻找区域中数据点的重心,或者加权平均值,将寻找中心移动到,数据点的重心处,并重复这个过程直到寻找区域重心收敛到一个稳定点。求图像像素点的分布直方图:#includecv.h#include #include #include using namespace cv;using namespace std;class Histogram1Dprivate : int histSize1; /项的数量 float hranges2; /像素的最大和最小值 const float* ranges1; /像素 int channels1; /通道数,这里表示只有一个通道。public: Hist
24、ogram1D() histSize0 = 256; hranges0 = 0.0; hranges1 = 255.0; ranges0 = hranges; channels0 = 0; /考察零号通道 MatND getHistogram(Mat &image) MatND hist; calcHist(&image, 1, channels, Mat(), hist, 1, histSize, ranges); return hist; Mat getHistogramImage(Mat &image) MatND hist = getHistogram(image); double m
25、axVal = 0; double minVal = 0; minMaxLoc(hist, &minVal, &maxVal, 0, 0);/查找数组中最大值和最小值的函数,第一个参数表示输入数组,第二三个表示最小大值的指针,第四五个表示最小大值的位置指针。 /得到显示直方图的图像: Mat histImg(histSize0, histSize0, CV_8U, Scalar(255); /设置最高点为nbins的90% int hpt = static_cast(0.9*histSize0);/依次划线 for (int h = 0; h histSize0; h+) float binV
26、al = hist.at(h); int intensity = static_cast(binVal*hpt / maxVal); line(histImg, Point(h, histSize0), Point(h, histSize0 - intensity),cvScalar(0,0,0); return histImg; ;void main() Mat Image = imread(beauty.jpg); Histogram1D h; MatND histo = h.getHistogram(Image); int sum = 0; for (int i = 0; i 256;
27、i+) cout 像素值为 i 的点有 histo.at(i) endl; sum = sum + histo.at(i); cout 汇总: sum endl; imshow(describe, h.getHistogramImage(Image); waitKey(0);运动物体检测:背景实时变化,把当前图像乘以一个均值加入背景中,主要是下面的cvRunningAvg函数/* 背景建模,运动物体检测*/#include #include #include #include int main(int argc, char* argv) /声明IplImage指针 IplImage* pFrame = NULL; IplImage* pFrImg = NULL; IplImage* pBkImg = NULL; CvMat* pFrameMat = NULL; CvMat* pFrMat = NULL; CvMat* pBkMat = NULL; CvCapture* pCapture = NUL
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1