vs2019使用opencv实现ViBe算法

参考代码网址:https://github.com/upcAutoLang/BackgroundSplit-OpenCV/tree/master/src/ViBe
链接
ViBe参考文章:https://www.jianshu.com/p/48baa72c6e5f
链接
(1)Vibe.h

#include<iostream>
#include<cstdio>
#include<opencv2/opencv.hpp>using namespace cv;
using namespace std;//每个像素点的样本个数默认值
#define DEFAULT_NUM_SAMPLES 20//#min指数默认值
#define DEFAULT_MIN_MATCHES 2//Sqthere半径默认值
#define DEFAULT_RADIUS 20//子采样概率默认值
#define DEFAULT_RANDOM_SAMPLE 16class ViBe
{public:ViBe(int num_sam = DEFAULT_NUM_SAMPLES,int min_match = DEFAULT_MIN_MATCHES,int r = DEFAULT_RADIUS,int rand_sam = DEFAULT_RANDOM_SAMPLE);~ViBe(void);//背景模型初始化void init(Mat img);//处理第一帧图像void ProcessFirstFrame(Mat img);//运行ViBe算法,提取前景区域并更新背景模型样本库void Run(Mat img);//获取前景模型二值图像Mat getFGModel();//删除样本库void deleteSamples();//x的邻居点int c_xoff[9];//y的邻居点int c_yoff[9];private://样本库unsigned char*** samples;//前景模型二值图像Mat FGModel;//每个像素点的样本个数int num_samples;//#min指数int num_min_matches;//Sqthere半径int radius;//子采样概率int random_sample;};

(2)Vibe.cpp

#include"Vibe.h"
/*
构造函数ViBe
参数:
int num_sam:每个像素点的样本个数
int min_match:#min 指数
int r: Sqthere 半径
int rand_sam:子采样概率
*/ViBe::ViBe(int num_sam, int min_match, int r, int rand_sam)
{num_samples = num_sam;num_min_matches = min_match;radius = r;random_sample = rand_sam;int c_off[9] = { -1,0,1,-1,1,-1,0,1,0 };for (int i = 0; i < 9; i++) {c_xoff[i] = c_yoff[i] = c_off[i];}
}/*析构函数:~ViBe说明:释放样本库内存
*/ViBe::~ViBe(void)
{deleteSamples();
}/*函数名init说明:背景模型初始化 为样本库分配空间参数:Mat img:源图像返回值:void
*/void ViBe::init(Mat img)
{//动态分配三维数组,samples[][][num_samples]存储前景被连续检测的次数//samples = new unsigned char** [img.rows];for (int i = 0; i < img.rows; i++){samples[i] = new uchar * [img.cols];for (int j = 0; j < img.cols; j++){//数组中,在num_samples之外多增加的一个值,用于统计该像素点连续成为前景的次数samples[i][j] = new uchar[num_samples + 1];for (int k = 0; k < num_samples + 1; k++){//创建样本库是,所有样本全部初始化为0samples[i][j][k] = 0;}}}FGModel = Mat::zeros(img.size(), CV_8UC1);
}
/*函数名 ProcessFirstFrame说明:处理第一帧图像读取视频序列第一帧,并随机选取像素点邻域内像素填充样本库,初始化背景模型参数:Mat img:源图像返回值:void*/void ViBe::ProcessFirstFrame(Mat img)
{RNG rng;int row, col;for (int i = 0; i < img.rows; i++){for (int j = 0; j < img.cols; j++){for (int k = 0; k < num_samples; k++){//随机选择num_samples个邻域像素点,构建背景模型int random;random = rng.uniform(0, 9); row = i + c_yoff[random];random = rng.uniform(0, 9); col = j + c_xoff[random];//防止选取的像素点越界if (row < 0)row = 0;if (row >= img.rows)row = img.rows - 1;if (col < 0)col = 0;if (col >= img.cols)col = img.cols - 1;//为样本库赋值随机值samples[i][j][k] = img.at<uchar>(row, col);}}}
}/*
函数名:Run
说明:运行ViBe算法,提取前景区域并更新背景模型样本库
参数:
Mat img 源图像
返回值:void*/void ViBe::Run(Mat img)
{RNG rng;int k = 0, dist = 0, matches = 0;for (int i = 0; i < img.rows; i++){for (int j = 0; j < img.cols; j++){//前景提取//说明:计算当前像素值与样本库的匹配情况//参数://int matches:当前像素值与   样本库中值之差小于阈值范围RADIUS的个数//int count: 遍历样本库的缓存变量for (k = 0,matches = 0; matches < num_min_matches && k < num_samples; k++){dist = abs(samples[i][j][k] - img.at<uchar>(i, j));if (dist < radius)matches++;}//说明:当前像素值与样本库中值匹配次数较高,则认为是背景像素点;//此时更新前景统计次数、更新前景模型、更新该像素模型样本值、更新该像素点邻域像素点if (matches >= num_min_matches){//已经认为是背景像素,故该像素前景统计次数置0samples[i][j][num_samples] = 0;//该像素点的前景模型像素值置0FGModel.at<uchar>(i, j) = 0;}//说明:当前像素值与样本库中值匹配次数较低,则认为是前景像素点//此时需要更新前景统计次数,判断更新前景模型else {//已经认为是前景像素,故该像素的前景统计次数+1samples[i][j][num_samples]++;//该像素点的前景模型像素值置255FGModel.at<uchar>(i, j) = 255;//如果某个像素点连续50次被检测为前景,则认为一块静止区域被误判为运动,将其更新为背景点if (samples[i][j][num_samples] > 50){int random = rng.uniform(0, num_samples);samples[i][j][random] = img.at<uchar>(i, j);}}//更新模型样本库if (matches >= num_min_matches){//已经认为该像素是背景像素,那么它有1/φ的概率去更新自己的模型样本值int random = rng.uniform(0, random_sample);if (random == 0){random = rng.uniform(0, num_samples);samples[i][j][random] = img.at<uchar>(i, j);}//同时也有1/φ的概率去更新它的邻居点的模型样本值random = rng.uniform(0, random_sample);if (random == 0){int row, col;random = rng.uniform(0, 9); row = i + c_yoff[random];random = rng.uniform(0, 9); col = j + c_xoff[random];//防止选取的像素点越界if (row < 0)row = 0;if (row >= img.rows)row = img.rows - 1;if (col < 0)col = 0;if (col >= img.cols)col = img.cols - 1;//为样本库赋值随机值random = rng.uniform(0, num_samples);samples[row][col][random] = img.at<uchar>(i, j);}}}  }
}/*
函数名 :getFGModel
说明:获取前景模型二值图像
返回值:Mat*/Mat ViBe::getFGModel()
{return FGModel;
}/*
函数名:deletesamples
说明:删除样本库
返回值:void*/void ViBe::deleteSamples()
{delete samples;
}

(3)main.cpp


#include<opencv2/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/types_c.h>
#include <opencv2/objdetect/objdetect.hpp>
#include "Vibe.h"int main(int argc, char* argv[])
{Mat frame, gray, FGModel;VideoCapture capture;capture = VideoCapture("./Video/cs2.mp4");if (!capture.isOpened()){capture = VideoCapture("../Video/cs2.mp4");if (!capture.isOpened()){capture = VideoCapture("../../Video/cs2.mp4");if (!capture.isOpened()){cout << "ERROR:Didn't find thid video!" << endl;return 0;}}}capture.set(CAP_PROP_FRAME_WIDTH, 160);capture.set(CAP_PROP_FRAME_HEIGHT, 120);if (!capture.isOpened()){cout << "No camera or video input!" << endl;return -1;}//程序运行时间统计变量double time;double start;ViBe vibe;bool count = true;while (1){capture >> frame;if (frame.empty())continue;cvtColor(frame, gray, CV_RGB2GRAY);if (count){vibe.init(gray);vibe.ProcessFirstFrame(gray);cout << "Training ViBe Success." << endl;count = false;}else{start = static_cast<double>(getTickCount());vibe.Run(gray);time = ((double)getTickCount() - start) / getTickFrequency() * 1000;cout << "Time of Update ViBe BAckground:" << time << "ms" << endl << endl;FGModel = vibe.getFGModel();imshow("FGModel", FGModel);}imshow("input", frame);if (waitKey(25) == 27)break;}return 0;
}

(4)视频
在项目文件夹下,新建了一个Video文件夹存放视频

(5)结果
找了个猫的视频,结果还行。
一开始找了个简短的电视剧视频,镜头一切换就又需要一段时间去判断背景和运动物体,效果不好。
最好找个背景是静止的视频,这样识别运动体效果会好。

vs2019使用opencv实现ViBe算法相关推荐

  1. 运动目标检测ViBe算法

    一.运动目标检测简介   视频中的运动目标检测这一块现在的方法实在是太多了.运动目标检测的算法依照目标与摄像机之间的关系可以分为静态背景下运动检测和动态背景下运动检测.先简单从视频中的背景类型来讨论. ...

  2. opencv-视频处理-实时的前景检测-Vibe算法

    vibe算法是一种像素级的前景检测算法,实时性高,内存占有率低,前景检测准确率高.但是会出现"鬼影",当然基于对鬼影的处理,也会有相应的对vibe算法的改进. 把下面三篇文章看明白 ...

  3. 运动目标检测ViBe算法的armadillo实现

    接上篇,最近在学习c++矩阵库,顺便把vibe算法用c++矩阵库armadillo做了一遍.虽然效果不理想,但是借这个机会算是把armadillo.Eigen.numcpp等几个注明的矩阵库都大致学习 ...

  4. 运动目标检测ViBe算法的numpy实现

    ViBe算法是一种优秀的运动目标检测,其背景建模是基于像素的邻域来建立,算法的具体原理我就不介绍了,网上可以搜到一大堆.网上提供的实现方法多是遍历图像中每个像素建立背景模型,有用c/c++实现的,也有 ...

  5. vs2019配置opencv,解决报错“无法打开源opencv2/opencv.hpp”

    目录 1,opencv下载地址 1.1 如何确定用什么版本的opencv opencv2和3的区别 opencv3和4的区别 1.2 source和exe 1.3 VC11.VC14.VC15库对应V ...

  6. OpenCV使用 GrabCut 算法进行交互式前景提取

    OpenCV使用 GrabCut 算法进行交互式前景提取 1. 效果图 2. 源码 参考 这篇博客将介绍如何使用Python,OpenCV中的GrabCut 算法来提取图像中的前景,并为此创建一个交互 ...

  7. pythonopencv算法_python opencv之分水岭算法示例

    本文介绍了python opencv之分水岭算法示例,分享给大家,具体如下: 目标 使用分水岭算法对基于标记的图像进行分割 使用函数cv2.watershed() 原理: 灰度图像可以被看成拓扑平面, ...

  8. VS2019配置opencv环境时找不到Microsoft.Cpp.x64.user.props

    安装下面方式,Microsoft.Cpp.x64.user.props有了 但是配置显示不可用: VS2019配置opencv环境时找不到Microsoft.Cpp.x64.user.props 用实 ...

  9. 背景建模--Vibe 算法改进

    背景建模--Vibe 算法改进 一.概述 针对鬼影问题,提出一种了基于前景区域与邻域背景区域直方图相似性度量的判别方法,检测并消除鬼影:针对静止目标问题,改进了Vibe背景模型的更新策略,有效抑制静止 ...

最新文章

  1. 基于 Spring Cloud 开发的分布式系统,遇到爬虫、接口盗刷怎么办?
  2. 使用Tensoflow实现梯度下降算法的一次线性拟合
  3. 【opencv】6.视频编码格式与封装格式
  4. [html] 你觉得新开发一个网站最困难的是哪些部分?
  5. 闲鱼前端基于serverless的一种多端开发解决方案
  6. c 子类对象 访问父类对象受保护成员_面向对象三大特征: 继承
  7. redis的批量操作命令pipeline(PHP实现)
  8. 深入Linux设备驱动程序内核机制
  9. org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com.demo.pojo.IdCard
  10. [内附完整源码和文档] 基于Java的高校科研管理系统
  11. Ackerman函数 非递归 java_ackerman(ackerman是谁)
  12. HTML学生个人网站作业设计:电影网站设计——叮当电影(5页) HTML+CSS+JavaScript 简单DIV布局个人介绍网页模板代码 DW学生个人网站制作成品下载
  13. AStar 拐点 算法实现AI寻路
  14. python 角度传感器模拟_模拟多圈旋转角度传感器
  15. 大三计算机保研er现在还能参加哪些竞赛?
  16. 大宗交易数据挖掘(一)
  17. Docker 技术鼻祖 Linux Namespace 入门系列:Namespace API
  18. 基于高光谱的无损检测技术
  19. 合成迪丽热巴下海_F4同台是虚拟合成,只有吴建豪到了现场,那F4其他三子呢?...
  20. 无盘网吧服务器能带30台机吗,30台机无盘网吧的配置方案

热门文章

  1. Saving James Bond(c++)
  2. HRNet——个人学习记录
  3. Mock和Spy的区别 打桩的区别
  4. matlab画阴影图
  5. axure 8 表格合并_规范交互原型图包含哪些要素? | 附Axure 模版源文件
  6. 伦敦金投资交易有哪些策略可以用?
  7. 玩转linux三剑客-三剑客实战经典例题
  8. 如何使用开发者工具?
  9. Java面试整理 -码之狼
  10. Ubuntu 14.04 LTS 英文环境下中文字体修改