OpenCV+python实现实时目标检测并保存视频
by zonegoalshall
前言
监控摄像头保存的视频中有大量的、无意义的“空”画面,于是导师提出,是否能实现:只有当检测到特定目标时才保存视频。于是便着手解决这个问题,并在此记录下解决问题的过程。完整的代码和说明在我的GitHub中。
version1.0
我们用到了OpenCV的dnn深度学习模块,预训练的MobilenetSSD模型,来实现。
Environments:
Ubuntu 16.04
python 2 or 3 都ok
OpenCV 3.4.2 注意,低版本OpenCV没有dnn,安装方法在此不赘述
requirements:
imutils0.5.2
numpy1.15.4
scikit-learn0.20.1
scipy1.1.0
sklearn==0.0
这些环境可以通过pip install -r requirements.txt
安装,当然,requirements.txt可在我的GitHub中找到。
- 获取当前时间 ,作为视频文件的文件名;
- 使用
cv2.readNetFromCaffe(args1, args2)
函数,传入部署文件 MobileNetSSD_deploy.prototxt.txt 和模型 MobileNetSSD_deploy.caffemodel ; - 打开 摄像头 ;
- 循环读取 当前帧 ,并将 当前帧
cv2.resize(frame, (300, 300)
重塑成可以传入 blob 的尺寸; - 再用
cv2.dnn.blobFromImage()
制作成 blob (注:blob是OpenCV的dnn模块处理图片的单位,可以理解为拥有同样大小、维度、通道等的图片或图片集) ; - 通过
net.setInput(bob)
把 blob 送入模型中,通过net.forward()
获取模型的反馈(detections
)。 - 在反馈(
detections
)中循环找出大于置信度的元素(即找出某个已知的目标),并通过它来索引 标签(注:在最开始初始化了20个标签,这里的问题我后面会讲); - 将检测到的目标框出,并在方框上打上标签,然后输出在窗口中,同时,在
7.
的循环中,当检测到目标是会用out.write(frame)
把 当前帧 拼接起来组成视频,按q
退出。
运行python real_time_object_detection.py --prototxt MobileNetSSD_deploy.prototxt.txt --model MobileNetSSD_deploy.caffemodel
,即可看到当前目录下有一段以运行时间为名存储的视频文件。
我们之前提到,我们用的是预训练模型,该模型被 “训练” 可识别20类目标,若我们希望它能只识别某个或者某几个目标,则需要重新训练,相关的方法网上也很多,也是我今后要着手改进的地方。
version2.0
在拥有 仅包含目标 的视频文件后,如何识别出文件中的人是谁?这里我们仍然用OpenCV的dnn模块,再加上两个预训练模型,resNet 来找出人脸,openface 来计算面部特征。前者是 caffe 框架的,后者是 torch 框架下的,在载入模型时有些许不同。
Environments:
Ubuntu 16.04
python 2 or 3 都ok
OpenCV 3.4.2 注意,低版本OpenCV没有dnn,安装方法在此不赘述
requirements:
imutils == 0.5.2
numpy ==1.15.4
完整项目环境可以通过pip install -r requirements.txt
安装,这里只列出了当前version所需。当然,requirements.txt可在我的GitHub中找到。
看看read-and-recog.py
代码做了些什么:
- 获取当前时间 ,作为视频文件的文件名(注:如果不想保存分析后的视频,可将此部分和后面某部分注释掉);
- 人脸识别 需要两个模型,在此我们都导入,caffe框架下的同之前, torch 框架下用这个函数
cv2.dnn.readNetFromTorch(args)
; - 同时我们还有装载 特征文档 和 标签文档(注:特征文档是在建立人脸库时计算出的,标签文档是在训练分类器时生成的,这两个文档怎么生成的将在version2.1中介绍);
- 找到人脸的过程和上述目标检测的过程是相似的,稍有不同的是,这里是从视频中读入帧,故而不再赘述;
- 当我们找到人脸后,用 openface 计算出当前脸的特征,将其和 特征文档 内的特征比对,若成功,则从 标签文档 中读出脸主姓名,画框并写名,这个过程和上述过程又有相似之处;
- 用
out.write(frame)
把 当前帧 拼接起来组成视频,按q
退出(注:如果不想保存分析后的视频,可将此部分和前面某部分注释掉)。
运行python read-and-recog.py --detector face_detection_model --embedding-model openface_nn4.small2.v1.t7 --recognizer output/recognizer.pickle --le output/le.pickle
如果你没有注释掉那两部分,你会看到当前目录下有一段以运行时间为名存储的视频文件。
version2.1
这里我要介绍一下怎么建立人脸库。
Environments:
Ubuntu 16.04
python 2 or 3 is ok
OpenCV 3.4.2 (above 3.3.1 is okay, for 3.3.0 does not have a dnn module.) Here I use make install, you can also install with pip.
requirements:
imutils == 0.5.2
numpy == 1.15.4
scikit-learn == 0.20.1
scipy == 1.1.0
sklearn == 0.0
可以通过pip install -r requirements.txt
安装,这里只列出了当前version所需。当然,requirements.txt可在我的GitHub中找到。
- 收集人脸照片,并将同一人的放入同一文件夹内,文件夹名为脸主人名;
- 运行
python extract_embeddings.py –dataset dataset --embeddings out/put embeddings.pickle --detector face_detection_model –embedding-model openface_nn4.small2.v1.t7
,流程和上述类似,这次将文件夹内的图片作为一帧输入,运行后我们得到了embeddings.pickle
文件; - 运行
python train_model.py –embeddings output/embeddings.pickle --recognizer output/recognizer.pickle --le output/le.pickle
,这里我们训练了一个 svm 分类器,这个分类器可以告诉我们哪些脸拥有哪些特征,运行后我们得到了recognizer.pickle
和le.pickle
;
这样我们有了两个必备的 pickle 文件,就可用来识别视频了
待续