注:以下所有内容,截选自实验楼项目教程【基于OpenCV实现实时监控并通过运动检测记录视频】
内容简介
- 实验使用PC机自带的摄像头作为监视器进行实时监控。
- 对原始图像做一定处理,使监控人员或监控软件更易发现监控中存在的问题。
- 当摄像头捕捉到运动产生时自动记录视频。
涉及知识点
本项目完成过程中将学习:
- 对摄像头数据的捕获
- 对捕获到的监控帧作背景处理
- 对监控视频做运动检测并记录视频
效果图
以下几张分别是程序在不同显示模式下的显示情况,你可以通过切换-mog1,-mog2和-src来自己观察对应的效果。
image.png 运行截图 运行截图 运行截图 运行截图实验环境
本实验需要先在实验平台安装 OpenCV ,需下载依赖的库、源代码并编译安装。安装过程建议按照教程给出的步骤,或者你可以参考官方文档中 Linux 环境下的安装步骤,但 有些选项需要变更。安装过程所需时间会比较长,这期间你可以先阅读接下来的教程,在大致了解代码原理后再亲自编写尝试。
我提供了一个编译好的2.4.13-binary.tar.gz
包,你可以通过下面的命令下载并安装,节省了编译的时间,通过这个包安装大概需要20~30分钟,视实验楼当前环境运转速度而定。
$ sudo apt-get update
$ sudo apt-get install build-essential libgtk2.0-dev libjpeg-dev libtiff5-dev libjasper-dev libopenexr-dev cmake python-dev python-numpy python-tk libtbb-dev libeigen2-dev yasm libfaac-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev libx264-dev libqt4-dev libqt4-opengl-dev sphinx-common texlive-latex-extra libv4l-dev libdc1394-22-dev libavcodec-dev libavformat-dev libswscale-dev
$ cd ~
$ mkdir OpenCV && cd OpenCV
$ wget http://labfile.oss.aliyuncs.com/courses/671/2.4.13-binary.tar.gz
$ tar -zxvf 2.4.13-binary.tar.gz
$ cd opencv-2.4.13
$ cd build
$ sudo make install
如果你想体验编译的整个过程,我也提供了一个一键安装的脚本文件,你可以通过下面的命令尝试。这个过程会非常漫长,约2小时,期间可能还需要你做一定的交互确认工作。
$ cd ~
$ sudo apt-get update
$ wget http://labfile.oss.aliyuncs.com/courses/671/opencv.sh
$ sudo chmod 777 opencv.sh
$ ./opencv.sh
如果你觉得有必要亲自尝试一下安装的每一步,可以按照下面的命令逐条输入执行,在实验楼的环境中大概需要两个小时。
$ sudo apt-get update
$ sudo apt-get install build-essential libgtk2.0-dev libjpeg-dev libtiff5-dev libjasper-dev libopenexr-dev cmake python-dev python-numpy python-tk libtbb-dev libeigen2-dev yasm libfaac-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev libx264-dev libqt4-dev libqt4-opengl-dev sphinx-common texlive-latex-extra libv4l-dev libdc1394-22-dev libavcodec-dev libavformat-dev libswscale-dev
$ wget https://github.com/Itseez/opencv/archive/2.4.13.zip
$ unzip 2.4.13.zip
$ cd 2.4.13
$ mkdir release && cd release
$ cmake -D WITH_TBB=ON -D BUILD_NEW_PYTHON_SUPPORT=ON -D WITH_V4L=ON -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=ON -D WITH_QT=ON -D WITH_GTK=ON -D WITH_OPENGL=ON ..
$ sudo make
$ sudo make install
$ sudo gedit /etc/ld.so.conf.d/opencv.conf
$ 输入 /usr/local/lib,按 Ctrl + X 退出,退出时询问是否保存,按 Y 确认。
$ sudo ldconfig -v
$ sudo gedit /etc/bash.bashrc
$ 在文件末尾加入
$ PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
按 Ctrl + X 退出,按 Y 确认保存。
检验配置是否成功。将 OpenCV 自带的例子(在目录PATH_TO_OPENCV/samples/C
下)运行检测。如果成功,将显示 lena 的脸部照片,同时圈出其面部。
$ cd samples/C
$ ./build_all.sh
$ ./facedetect --cascade="/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml" --scale=1.5 lena.jpg
实验原理
实验通过 OpenCV 提供的 API 完成大部分任务,首先捕获摄像头数据,之后对捕获到的每一帧作背景减除处理,得出易于识别的图像,最后利用直方图做实时图像和背景图像的对比,实现运动检测并写入视频文件。
实验步骤
通过以下命令可下载项目源码,作为参照对比完成下面详细步骤的学习。
wget http://labfile.oss.aliyuncs.com/courses/671/monitor-recorder.zip
unzip monitor-recorder.zip
1.定义头文件
工程文件由一个头文件 monitor.hpp 和一个入口文件 main.cpp 构成。首先在头文件中定义将使用的库和相关变量。
代码中使用到的 OpenCV 头文件和 C++ 头文件在头文件 monitor.hpp 中声明如下,其中 unistd.h 包含了 Linux 下的 sleep 函数,参数为睡眠的秒数。
#ifndef __MONITOR_H_
#define __MONITOR_H_
//opencv
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/imgproc/imgproc.hpp>
//C++
#include <ctime>
#include <iostream>
#include <string>
#include <cstdio>
#include <unistd.h>
#include <sstream>
using namespace cv;
using namespace std;
// ...
#endif __MONITOR_H_
2.设计 processCamera 函数
processCamera 负责完成主要功能,包括监控数据的获取和处理。首先要了解 OpenCV 中提供的几个 API。
- CvCapture* cvCaptureFromCAM(int device): 此函数捕获指定设备的数据并返回一个 cvCapture 类型指针,捕获失败时返回 NULL。
- cvCreateFileCapture(char * filepath): 从本地视频读入。
- CvVideoWriter * cvCreateVideoWriter(char * filepath, , fps, size, is_color): 新建一个视频写入对象,返回其指针,filepath指定写入视频的路径,fps指定写入视频的帧速,size指定写入视频的像素大小,is_color仅在windows下有效,指定写入是否为彩色。
- double cvGetCaptureProperty(CvCapture* capture, int property_id): 获取一个视频流的某个特性,property_id指定要获取的特性名称。
- IplImage* cvQueryFrame(CvCapture* capture): 从视频流获取帧。
- void cvCvtColor(const CvArr* src, CvArr* dst, int code): 按code指定的模式将src指向的帧转换后写入dst指向的地址。
- void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, SparseMat& hist, int dims, const int* histSize, const float** ranges, bool uniform, bool accumulate): 为image指向的帧计算直方图,保存在 hist 中。
- void normalize(const SparseMat& src, SparseMat& dst, double alpha, int normType): 按指定模式将src正常化并写入dst中。
- double compareHist(const SparseMat& H1, const SparseMat& H2, int method):按method指定的方式比较两个直方图的相似程度。
- int cvWriteFrame(CvVideoWriter* writer, const IplImage* image): 向视频写入流写入一帧。成功返回 1,否则返回 0。
了解这些API的基本功能后,梳理程序执行的步骤:
- 程序开始执行,启动摄像头并获得数据流
- 进入循环:
- 捕获一帧
- 是否为第一帧?是则记录该帧作为监控区域的背景
- 将该帧做适当的变换,输出到监视器中
- 分析该帧和背景帧的相似程度
- 相似程度是否低于阈值且当前没有在记录视频?低于阈值开始记录。
- 相似程度是否低于阈值且当前已经开始记录视频?低于阈值继续记录,否则停止记录。
- 循环中程序的停止,通过接受外部中断相应。
上面介绍了实验原理以及环境配置等,关于具体怎样开发,主要在下面几点内容:
3.代码实现 processCamera
4.定义外部或全局变量
5.编写 main.cpp
6.编译运行
由于篇幅有限,所以剩下的开发详细步骤和代码,点击【基于OpenCV实现实时监控并通过运动检测记录视频】即可查看了~
网友评论