ViBe的C++实现

xiaoxiao2021-02-28  117

//ViBe.h #ifndef VIBE_H_ #define VIBE_H_ #include<iostream> #include<string> #include<opencv.hpp> #include <ctype.h> #include <stdio.h> using namespace std; using namespace cv; #define SAMPLE_SET_NUMBER 20//样本模型个数 #define DADIUS 20//距离相近判定的阈值 #define THRESHOLD_MIN 5//判定属于前景还是背景的阈值 #define UPDATE_PROBABLLITY 16//子采样概率 #define FOREGROUND_NUMBER 50//如果某个像素点连续FOREGROUND_NUMBER次被检测为前景,则将其更新为背景点 class vibe { private: Mat sample_set[SAMPLE_SET_NUMBER]; Mat vibe_image; Mat temp_image; public: vibe(); ~vibe(); void InitialImage(const Mat image); void InitialFirstFrame(const Mat image);//模型的初始化 Mat TestAndSampleUpdate(const Mat image);//测试和模型的更新 }; #endif

//ViBe.cpp #include"stdafx.h" #include"ViBe.h" int x[9] = { -1, 0, 1, -1, 1, -1, 0, 1, 0 }; int y[9] = { -1, 0, 1, -1, 1, -1, 0, 1, 0 }; vibe::vibe() {} vibe::~vibe() {} void vibe::InitialImage(const Mat image) { for (int i = 0; i < SAMPLE_SET_NUMBER; i++) { sample_set[i] = Mat::zeros(image.size(),image.type()); } vibe_image = Mat::zeros(image.size(), image.type()); temp_image = Mat::zeros(image.size(), image.type()); } //模型的初始化 void vibe::InitialFirstFrame(const Mat image) { RNG rng; int r, c; for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { for (int k = 0; k < SAMPLE_SET_NUMBER; k++) { int random = rng.uniform(0, 9); r = i + x[random]; if (r < 0) r = 0; if (r >= image.rows) r = image.rows - 1; c = j + y[random]; if (c < 0) c = 0; if (c >= image.cols) c = image.cols - 1; sample_set[k].at<uchar>(i, j) = image.at<uchar>(r, c); } } } } //测试和模型的更新 Mat vibe::TestAndSampleUpdate(const Mat image) { RNG rng; for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { int count = 0; for (int k = 0; k < SAMPLE_SET_NUMBER; k++) { int d=abs(image.at<uchar>(i, j) - sample_set[k].at<uchar>(i, j)); if (d < DADIUS) count++; } if (count >= THRESHOLD_MIN)//判定属于背景点 { vibe_image.at<uchar>(i, j) = 0; temp_image.at<uchar>(i, j) = 0; //背景点的模型更新 //若该像素是背景点,那么有1/UPDATE_PROBABLLITY的概率更新样本模型值 int random1 = rng.uniform(0, UPDATE_PROBABLLITY); if (random1 == 0) { int itemp = rng.uniform(0, SAMPLE_SET_NUMBER); sample_set[itemp].at<uchar>(i, j) = image.at<uchar>(i, j); } //若该像素是背景点,那么有1/UPDATE_PROBABLLITY的概率更新临近点的样本模型值 int random2 = rng.uniform(0, UPDATE_PROBABLLITY); if (random2 == 0) { int ran = rng.uniform(0, 9); int r = i + x[ran]; if (r < 0) r = 0; else if (r >= image.rows) r = image.rows - 1; int c = j + y[ran]; if (c < 0) c = 0; else if (c >= image.cols) c = image.cols - 1; int itemp = rng.uniform(0, SAMPLE_SET_NUMBER); sample_set[itemp].at<uchar>(r, c) = image.at<uchar>(i, j); } } else { vibe_image.at<uchar>(i, j) = 255; temp_image.at<uchar>(i, j)++; //如果某个像素点连续N次被检测为前景,则认为一块静止区域被误判为运动,将其更新为背景点 if (temp_image.at<uchar>(i, j)>FOREGROUND_NUMBER) { int random = rng.uniform(0, SAMPLE_SET_NUMBER); if (random == 0) { random = rng.uniform(0, SAMPLE_SET_NUMBER); sample_set[random].at<uchar>(i, j) = image.at<uchar>(i, j); } } } } } return vibe_image; } //main.cpp #include"stdafx.h" #include"ViBe.h" int main() { vibe vibetemp; Mat gray,dst_iamge; string openfile = "camera1.avi"; string outfile = "out.avi"; //打开视频文件 VideoCapture capture(openfile); if (!capture.isOpened()) { cout << "video file open error!\n"; return -1; } //获取视频帧率、大小和总帧数 double fps = capture.get(CV_CAP_PROP_FPS);//获取视频文件的帧率 int frame_width = (int)capture.get(CV_CAP_PROP_FRAME_WIDTH); int frame_height = (int)capture.get(CV_CAP_PROP_FRAME_HEIGHT); cout << "frame_width:" << frame_width << endl; cout << "frame_height" << frame_height << endl; int frame_number = capture.get(CV_CAP_PROP_FRAME_COUNT);//总帧数 cout << "frame_number" << frame_number << endl; //创建输出视频文件 VideoWriter Save_result(outfile, CV_FOURCC('M', 'J', 'P', 'G'), fps, Size(frame_width, frame_height),false); //Mat dstImg(frame_height, frame_width, IPL_DEPTH_8U, 3);//创建要保存的图像 int nFrmNum = 0; //逐帧读取视频并进行处理 while (true) { nFrmNum++; cout << nFrmNum << endl; Mat frame; capture >> frame;//读出每一帧的图像 if (frame.empty()) { cout << "over" << endl; break; } cvtColor(frame, gray, CV_BGR2GRAY); if (nFrmNum == 1) { vibetemp.InitialImage(gray); vibetemp.InitialFirstFrame(gray); cout << "Initial first frame complete!" << endl; } else { dst_iamge=vibetemp.TestAndSampleUpdate(gray); morphologyEx(dst_iamge, dst_iamge, MORPH_OPEN, Mat());//开运算 Save_result << dst_iamge; imshow("dst_iamge", dst_iamge); waitKey(1); } } return 0; }

转载请注明原文地址: https://www.6miu.com/read-25694.html

最新回复(0)