嵌入式linux开发 (18)
机器学习笔记 (24)
收藏的一些好文 (3)
写点什么 (13)
关于网站 (4)
ubuntu系统教程 (24)
Debian系统教程 (16)
windows软件开发 (21)
数字信号处理 (11)
嵌入式开发笔记 (26)
电路设计与调试 (9)
打工琐记 (25)
CC3200开发 (5)
C/C++开发笔记 (14)
PHP后端服务开发 (18)
计算机视觉 (29)
FPGA 开发 (5)
5G NR (2)
Python软件开发 (5)
云计算 (0)
计算机程序与解释 (4)
Web前端 (1)
软核OR1200 (6)
Cortex-M0开发笔记 (12)
LiteOS笔记 (1)
tinify
Cortex-M0异常中断
LAMP
可变数据类型
VerilogHDL
Linux文件系统
php
ubuntu14.04
NR
设计需求
逻辑电平阈值
make控制函数
Cortex-M0中断控制
嵌入式
通信
期望
正态分布
git
S3C2440
CCS4
Cygwin
Maven
Verilog
无免费午餐理论
Debian系统
可视化工具
LM393芯片使用
cuda8.0
arm-linux-gcc
A3
硬件
物体切割
深度学习
抽象边界
库函数
预测
GatewayWorker
gnumake
firefox提速
网络功能
条件语句
函数环境
Allegro
STM32
VHDL
服务器迁移
Win7
轮廓检测
网络配置
make指示符
数据抽象
编译环境
ubuntu16.04
python
vmware
感知层
Cortex-M0编程
电源
无线网卡
svn服务器
在上篇博文
《OpenCV3-Python简单移动目标跟踪》
中介绍了简单移动目标跟踪方法,也提到在实际应用中,由于场景复杂其跟踪效果并不好;因此,本篇介绍常用的几种更有效的跟踪方法——背景分割器。
1. 背景分割器
OpenCV3中常用的背景分割器有三种:Mixture of Gaussians(MOG2)、K-Nearest(KNN)、Geometric Multigid(GMG) 。
OpenCV中提供了一个称为BackgroundSubtractor的类,在分割前景和背景时有两方面的优势:
<1> 专门用来进行视频分析,即:BackgroundSubtractor类会对每帧的环境进行 "学习" ;
<2> 可以计算阴影,通过检测阴影,可排除检测图像的阴影区域,从而更关注实际特征;
2. 应用举例
(1)MOG2
import cv2
import numpy as np
retval = cv.createBackgroundSubtractorMOG2( [, history[, varThreshold[, detectShadows]]] )
Parameters
history Length of the history.
varThreshold Threshold on the squared Mahalanobis distance between the pixel and the model to decide whether a pixel is well described by the background model. This parameter does not affect the background update.
detectShadows If true, the algorithm will detect shadows and mark them. It decreases the speed a bit, so if you do not need this feature, set the parameter to false.
url: https://docs.opencv.org/3.4.2/de/de1/group__video__motion.html#ga2beb2dee7a073809ccec60f145b6b29c
#MOG背景分割器
mog = cv2.createBackgroundSubtractorMOG2(detectShadows = True)
camera = cv2.VideoCapture("traffic.flv")
ret, frame = camera.read()
while ret:
fgmask = mog.apply(frame)
th = cv2.threshold(np.copy(fgmask), 244, 255, cv2.THRESH_BINARY)[1]
th = cv2.erode(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)), iterations = 2)
dilated = cv2.dilate(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (8,3)), iterations = 2)
image, contours, hier = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
if cv2.contourArea(c) > 1000:
(x,y,w,h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x,y), (x+w, y+h), (255, 255, 0), 2)
cv2.imshow("mog", fgmask)
cv2.imshow("thresh", th)
cv2.imshow("diff", frame & cv2.cvtColor(fgmask, cv2.COLOR_GRAY2BGR))
cv2.imshow("detection", frame)
ret, frame = camera.read() #读取视频帧数据
if cv2.waitKey(100) & 0xff == ord("q"):
break
camera.release()
cv2.destroyAllWindows()
(2)KNN
import cv2
import numpy as np
retval = cv.createBackgroundSubtractorKNN([, history[, dist2Threshold[, detectShadows]]])
Parameters
history Length of the history.
dist2Threshold Threshold on the squared distance between the pixel and the sample to decide whether a pixel is close to that sample. This parameter does not affect the background update.
detectShadows If true, the algorithm will detect shadows and mark them. It decreases the speed a bit, so if you do not need this feature, set the parameter to false.
#KNN背景分割器
knn = cv2.createBackgroundSubtractorKNN(detectShadows = True)
camera = cv2.VideoCapture("traffic.flv")
def drawCnt(fn, cnt):
if cv2.contourArea(cnt) > 1600:
(x, y, w, h) = cv2.boundingRect(cnt)
cv2.rectangle(fn, (x, y), (x + w, y + h), (255, 255, 0), 2)
while True:
ret, frame = camera.read()
if not ret:
break
fgmask = knn.apply(frame)
th = cv2.threshold(np.copy(fgmask), 244, 255, cv2.THRESH_BINARY)[1]
es = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
dilated = cv2.dilate(th, es, iterations = 2)
image, contours, hierarchy = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
drawCnt(frame, c)
cv2.imshow("knn", fgmask)
cv2.imshow("thresh", th)
cv2.imshow("detection", frame)
if cv2.waitKey(100) & 0xff == ord("q"):
break
camera.release()
cv2.destroyAllWindows()
(2)GMG
import numpy as np
import cv2
retval = cv.bgsegm.createBackgroundSubtractorGMG( [, initializationFrames[, decisionThreshold]] )
Parameters
initializationFrames number of frames used to initialize the background models.
decisionThreshold Threshold value, above which it is marked foreground, else background.
#GMG背景分割器
fgbg = cv2.bgsegm.createBackgroundSubtractorGMG()
camera = cv2.VideoCapture('traffic.flv')
ret, frame = camera.read()
while ret:
fgmask = fgbg.apply(frame)
th = cv2.threshold(np.copy(fgmask), 244, 255, cv2.THRESH_BINARY)[1]
th = cv2.erode(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)), iterations = 2)
dilated = cv2.dilate(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (8,3)), iterations = 2)
image, contours, hier = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
if cv2.contourArea(c) > 1000:
(x,y,w,h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x,y), (x+w, y+h), (255, 255, 0), 2)
cv2.imshow("GMG", fgmask)
cv2.imshow("thresh", th)
cv2.imshow("diff", frame & cv2.cvtColor(fgmask, cv2.COLOR_GRAY2BGR))
cv2.imshow("detection", frame)
ret, frame = camera.read() #读取视频帧数据
if cv2.waitKey(100) & 0xff == ord("q"):
break
camera.release()
cv2.destroyAllWindows()
根据以上效果对比知:
MOG2算法阴影检测并不完美,但它有助于将目标轮廓按原始形状进行还原;KNN的精确性和阴影检测能力较好,即使是相邻对象也没有在一起检测,运动检测的结果相当精确。
下一篇:
《OpenCV3-Python基于Kalman和CAMShift算法应用》