传统运动物体检测方法的Python实现

文章目录

  • 传统运动物体检测方法的Python实现
  • 一、目标跟踪算法综述
    • 1. 传统方法:特征提取+滤波类搜索算法
    • 2. 深度学习方法: 目标检测和相似度匹配
  • 二、Python实现
    • 0.引入库
    • 1. 帧差法
      • (1)二帧法
      • (2)三帧法
    • 2. 背景减除法
    • 3. 光流法
      • (1)实现流程
      • (2)Python代码
  • 三、完整代码

一、目标跟踪算法综述

视觉目标(单目标)跟踪任务就是在给定某视频序列初始帧的目标大小与位置的情况下,预测后续帧中该目标的大小与位置

1. 传统方法:特征提取+滤波类搜索算法

(1) 帧差法、光流法、背景减除法
(2) 相关滤波法

2. 深度学习方法: 目标检测和相似度匹配

(1) tracking-by-detection方式:
主要针对目标检测算法和滤波类算法(多目标跟踪),yolo系列、SSD系列、anchor-free系列、two-stage系列等等,滤波类和上述传统方式相似。
(2) 基于Siamese Networks(生成式,主要针对单目标):
主要通过Siamese网络进行相似度匹配,主要操作为:首先手动选择初始图像中的目标,使用Siamese网络进行特征提取,然后以此特征为标准,遍历后面帧图像的每个位置,对每个位置进行特征提取,然后做比较,确定位置。

二、Python实现

0.引入库

代码如下:

import cv2
import numpy as np

1. 帧差法

(1)二帧法

当前帧与前一帧差分,核心代码如下:

# 当前帧
tempFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 差分帧
disFrame = cv2.absdiff(tempFrame, last_frame)
# 中值滤波去噪
median = cv2.medianBlur(disFrame, 3)
# 二值化
ret, threshold_frame = cv2.threshold(median, 20, 255, cv2.THRESH_BINARY)
# 高斯模糊
gauss_image = cv2.GaussianBlur(threshold_frame, (3, 3), 0)
# 更新,便于下一次差分
last_frame = tempFrame

(2)三帧法

对于连续的三帧,12相减,23相减,然后将两次差分的结果做与运算作为最终结果,相比于二帧法可以消除微小抖动的影响。核心代码如下:

# 当前帧
temp_frame = frame_gray
# 12差分
dis_frame1 = cv2.absdiff(frame2, frame1)
_, thresh1 = cv2.threshold(dis_frame1, 40, 255, cv2.THRESH_BINARY)  # 二值,大于40的为255,小于0
# 23差分
dis_frame2 = cv2.absdiff(temp_frame, frame2)
_, thresh2 = cv2.threshold(dis_frame2, 40, 255, cv2.THRESH_BINARY)  # 二值,大于40的为255,小于0
# 与运算
dis_frame = cv2.bitwise_and(thresh1, thresh2)  # 二值化图像
# 更新,便于下一次差分
frame1, frame2 = frame2, temp_frame

2. 背景减除法

采用OpenCV的createBackgroundSubtractorMOG2实现。
这个也是以高斯混合模型为基础的背景 / 前景分割算法。它是以2004年和2006年Z.Zivkovic的两篇文章为基础的。这个算法的一个特点是它为每
一个像素选择一个合适数目的高斯分布。这样就会对由于亮度等发生变化引起的场景变化产生更好的适应。

cv2.createBackgroundSubtractorMOG2(history, varThreshold, detectShadows)

该方法可以选择是否检测阴影。如果detectShadows = True(默认值),它就会检测并将影子标记出来,但是这样做会降低处理速度。影子会被标记为灰色。

fgbg = cv2.createBackgroundSubtractorMOG2()
fgmask = fgbg.apply(frame)

3. 光流法

所谓光流就是瞬时速率,在时间间隔很小(比如视频的连续前后两帧之间)时,也等同于目标点的位移

(1)实现流程

(1)首先获取视频或者摄像头的第一帧图像 用goodFeaturesToTrack函数获取初始化的角点
(2)然后开始无限循环获取视频图像帧 将新图像和上一帧图像放入calcOpticalFlowPyrLK函数当中,从而获取新图像的光流。

使用光流法的前提假设:
(1)相邻帧之间的亮度恒定
(2)相邻视频帧的取帧时间连续,或者,相邻帧之间物体的运动比较“微小”;
(3)保持空间一致性;即,同一子图像的像素点具有相同的运动

(2)Python代码

# 从第一帧中选择利于跟踪的特征
p0 = cv2.goodFeaturesToTrack(frame0_gray, mask=None, **feature_params)  # **param 关键字参数
mask = np.zeros_like(frame0)
tempFrame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
p1, st, err = cv2.calcOpticalFlowPyrLK(frame0_gray, tempFrame_gray, p0, None, **lk_params)
# 选取好的跟踪点
good2track_temp = p1[st == 1]
good2track_0 = p0[st == 1]
# 更新上一帧的图像和追踪点
old_gray = tempFrame_gray.copy()
p0 = good2track_0.reshape(-1, 1, 2)

三、完整代码

运行环境:Python3.8、OpenCV-Python4.5.5.62

# _*_ coding: utf-8 _*_
# @time : 2022/1/12  16:29
# @name : traditionalMethod.py
# @author : 霜晨月~
import cv2
import numpy as np# 1.1、帧差分法-->二帧法
def dis_2frame():cap = cv2.VideoCapture(0)width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))last_frame = np.zeros((height, width), dtype=np.uint8)  # 前1帧num = 0if not cap.isOpened():print('Error opening video or file!')while cap.isOpened():  # 视频打开成功ret, frame = cap.read()if ret:# 当前帧tempFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 差分帧disFrame = cv2.absdiff(tempFrame, last_frame)# 中值滤波去噪median = cv2.medianBlur(disFrame, 3)# 二值化ret, threshold_frame = cv2.threshold(median, 20, 255, cv2.THRESH_BINARY)# 高斯模糊gauss_image = cv2.GaussianBlur(threshold_frame, (3, 3), 0)cv2.imshow('dis_medianBlur_threshold_gaussianBlur', gauss_image)# 更新,便于下一次差分last_frame = tempFramenum += 1if cv2.waitKey(20) & 0xFF == 27:cv2.destroyAllWindows()breakcap.release()# 1.2、帧差分法-->三帧法:12相减,23相减,与运算
def dis_3frame():cap = cv2.VideoCapture(0)width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))frame1 = np.zeros((height, width), dtype=np.uint8)  # 前2帧 1frame2 = frame1  # 前1帧 2num = 0if not cap.isOpened():print('Error opening video or file!')while cap.isOpened():  # 视频打开成功ret, frame = cap.read()frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)if ret:# 当前帧temp_frame = frame_gray# 12差分dis_frame1 = cv2.absdiff(frame2, frame1)_, thresh1 = cv2.threshold(dis_frame1, 40, 255, cv2.THRESH_BINARY)  # 二值,大于40的为255,小于0# 23差分dis_frame2 = cv2.absdiff(temp_frame, frame2)_, thresh2 = cv2.threshold(dis_frame2, 40, 255, cv2.THRESH_BINARY)  # 二值,大于40的为255,小于0# 与运算dis_frame = cv2.bitwise_and(thresh1, thresh2)  # 二值化图像# 形态学去噪kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))erode = cv2.erode(dis_frame, kernel)  # 腐蚀# dilate = cv2.dilate(erode, kernel)  # 膨胀# dilate = cv2.dilate(dilate, kernel)  # 膨胀img, contours, hei = cv2.findContours(erode.copy(), mode=cv2.RETR_EXTERNAL,method=cv2.CHAIN_APPROX_SIMPLE)  # 寻找轮廓for contour in contours:if 100 < cv2.contourArea(contour) < 40000:x, y, w, h = cv2.boundingRect(contour)  # 找方框cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255))cv2.namedWindow("binary", cv2.WINDOW_NORMAL)cv2.namedWindow("dilate", cv2.WINDOW_NORMAL)cv2.namedWindow("frame", cv2.WINDOW_NORMAL)cv2.imshow("binary", dis_frame)cv2.imshow("dilate", erode)cv2.imshow("frame", frame)# 更新,便于下一次差分frame1, frame2 = frame2, temp_framenum += 1if cv2.waitKey(20) & 0xFF == 27:cv2.destroyAllWindows()breakcap.release()# 2、背景减除法
def createBackground():cap = cv2.VideoCapture(0)# kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))# fgbg = cv2.bgsegm.createBackgroundSubtractorGMG()fgbg = cv2.createBackgroundSubtractorMOG2()while cap.isOpened():ret, frame = cap.read()fgmask = fgbg.apply(frame)# fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)cv2.imshow('fgmask', fgmask)if cv2.waitKey(20) & 0xFF == 27:cv2.destroyAllWindows()breakcap.release()# 3、光流法
def lightFlow():cap = cv2.VideoCapture(0)feature_params = dict(maxCorners=100, qualityLevel=0.3, minDistance=7, blockSize=7)  # ShiTomasi 角点检测参数ret, frame0 = cap.read()w, h = cap.get(3), cap.get(4)FPS = cap.get(5)print('size:', w, h)print('FPS:', FPS)frame0_gray = cv2.cvtColor(frame0, cv2.COLOR_BGR2GRAY)p0 = cv2.goodFeaturesToTrack(frame0_gray, mask=None, **feature_params)  # **param 关键字参数mask = np.zeros_like(frame0)  # 创建一个蒙版用来画轨迹,i.e.和每帧图像大小相同的全0张量lk_params = dict(winSize=(15, 15), maxLevel=2,criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))  # lucas kanade光流法参数color = np.random.randint(0, 255, (100, 3))  # 创建随机颜色while cap.isOpened():ret, frame = cap.read()tempFrame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)p1, st, err = cv2.calcOpticalFlowPyrLK(frame0_gray, tempFrame_gray, p0, None, **lk_params)# 选取好的跟踪点good2track_temp = p1[st == 1]good2track_0 = p0[st == 1]# 画出轨迹for i, (new, old) in enumerate(zip(good2track_temp, good2track_0)):a, b = new.ravel()c, d = old.ravel()mask = cv2.line(mask, (int(a), int(b)), (int(c), int(d)), color[i].tolist(), 2)  # 添加了该帧光流的轨迹图frame = cv2.circle(frame, (int(a), int(b)), 5, color[i].tolist(), -1)img = cv2.add(frame, mask)  # 将该图和轨迹图合并cv2.imshow('frame', img)if cv2.waitKey(20) & 0xFF == 27:cv2.destroyAllWindows()break# 更新上一帧的图像和追踪点old_gray = tempFrame_gray.copy()p0 = good2track_0.reshape(-1, 1, 2)cap.release()if __name__ == '__main__':dis_2frame()# dis_3frame()# createBackground()# lightFlow()

传统运动物体检测方法的Python实现相关推荐

  1. python运动物体检测_运动检测ViBe算法python实现代码

    运动物体检测一般分为背景建模和运动物体分析两步.即构建不包含运动物体的背景模型.然后将新的视频帧和背景模型对比,找出其中的运动物体.目前比较好的背景建模算法有两种:1)文章(Zivkovic Z. ( ...

  2. 【opencv学习】【运动物体检测】

    今天学习运动物体检测 一:帧差法 捕获摄像头的运动的手 import cv2 import numpy as np# 如果我们想捕获一些运动的物体,每一帧图像中,不动的部分称之为背景,运动的物体称之为 ...

  3. 基于尺寸划分的RGB显著物体检测方法

    SDCNet: Size Divide and Conquer Network for Salient Object Detection Senbo Yan, Xiaowen Song, and Ch ...

  4. 判断图像局部过暗_CVPR 2020丨基于记忆增强的全局局部整合网络:更准确的视频物体检测方法...

    编者按:在视频物体检测任务中,由于相机失焦.物体遮挡等问题,仅基于图像的目标检测器很可能达不到令人满意的效果.针对此类问题,微软亚洲研究院提出了基于记忆增强的全局-局部整合网络(Memory Enha ...

  5. BBAVectors:一种Anchor Free的旋转物体检测方法

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 导读 WACV2021的一篇文章,将CenterNet的方案用到了 ...

  6. Python-OpenCV运动物体检测

    运动物体检查,在移动目标定位和智能安防系统中有广泛的应用,它的实现原理:捕获连续帧之间的变化情况,将每次捕获的图像进行对比,然后检查差值图像中的所有斑块(颜色相近的地方). Demo在实现的过程中,首 ...

  7. Emgu CV4图像处理之运动物体检测16(C#)

    本文测试环境: win10  64位 vistual studio 2019 Emgu CV 4.6.0 环境配置准备: 1 新增控制台项目,.net framework为4.7.2 2  把win- ...

  8. 光流 | 基于光流的实时运动物体检测(MATLAB代码)

    ===================================================== github:https://github.com/MichaelBeechan CSDN: ...

  9. 三帧差分法 - 运动物体检测 - 行人检测 - 学习研究过程

    三帧差分法 1. 什么是三帧差分法 关于原理,请点击下面的连接,进行了解: 三帧差分法 说的通俗一点,这个流程就是: 1.1 (第二幅图像 - 第一幅图像) ∩ (第三幅图像 - 第二幅图像) = 结 ...

最新文章

  1. maven不能加载ojdbc6.jar的解决方法
  2. ASP.NET页面生命周期与应用程序生命周期
  3. php中的static
  4. centos 显示50g硬盘但是 实际大小很小_天啦噜!知道硬盘很慢,但没想到比 CPU Cache 慢 10000000 倍...
  5. Halcon:二维仿射变换实例探究
  6. exchanger_如何通过示例在Java中使用Exchanger
  7. 物理层协议有哪四大特性
  8. vue项目打包成app
  9. 每个国家对应的values语言Locale和国家代码对照表
  10. 传奇中添加NPC及功能脚本
  11. 记一次搭建 nodebb 论坛
  12. [日推荐] 『雅思口语自练狂』雅思考试神助攻!
  13. 【工大SCIR】AAAI20 基于反向翻译和元学习的低资源神经语义解析
  14. 可以检测手机帧率和温度的软件_拯救者电竞手机Pro评测:不只是一台手机,更是游戏主机...
  15. 基带qcn的备份与写入相关 格机 nv报错
  16. 计算机科学与技术毕业自我鉴定,2016届计算机科学与技术专业大学生毕业自我鉴定优秀范文...
  17. adobe reader xi补丁_Adobe Reader XI
  18. Androidproject师进阶之路 :《Android开发进阶:从小工到专家》上市啦!
  19. 信息安全原理与实践(第2版) [Mark Stamp 著][张戈 译] PDF完整版
  20. 【蓝桥杯选拔赛真题21】python5个正整数 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析

热门文章

  1. 镶嵌数据集工具小结(八)色彩平衡与接缝线 Ⅱ
  2. excel函数去重_Excel 2010中去除重复项的几种常用技巧
  3. 5G关键技术之波束成型
  4. 饥荒联机版Centos下自动更新教程
  5. revit出图建模【尺寸定位标注】功能
  6. Google Maps基站定位
  7. Java 安全-JNDI注入学习
  8. 【EasyUI篇】一整套EasyUI示例集锦
  9. Hadoop+hive+flask+echarts大数据可视化项目之hive环境搭建与系统数据的分析思路
  10. 《如何启动黄金圈思维》苹果和微软都在用的“思维模型”