使用 OpenCV 进行运动检测

Mediapipe+OpenCV与Unity引擎实现动作捕捉 因为之前的写的人物动作捕捉是先通过Python和Mediapipe先将人物动作进行捕捉,将捕捉到的数据format后写入到txt中,在Unity端对txt进行数据读取,进而实现Unity人物运动;**其中的缺点是:没有时效性** **而本次的改进:通过利用socket和UPD通信,在localhost中数据传输,让动捕数据实时传输,到达实时动捕的效果... 阅读详情

概览

最近在做一个项目的时候需要检测摄像头拍摄范围内的图像是否有变化,即需要进行运动检测,在检测到运动之后录制 5 秒的视频存档。
在查阅了一些资料之后,发现了一种效果不错的方法(原始文章见参考内容 1),该方法只进行运动检测,不进行追踪。该方法的主要思路就是计算连续帧之间的差距,如果该差距较大,我们就认为画面的内容发生了变化。其中为了避免假阳性,该方法计算了帧差的标准差。
算法的主要流程如下:

  1. 计算帧间的距离(Pythagorean distance)
  2. 在计算出来的距离矩阵上应用高斯模糊
  3. 使用一定的阈值进行过滤
  4. 计算标准差
  5. 标准差大于一定的阈值,认为检测到了运动,输出信息

本文将给出 Python 和 C++ 两种语言的实现。

运行环境

操作系统:ARMBIAN 5.38 stable Ubuntu 16.04.3 LTS 3.4.113-sun8i
编程环境:Python 2.7.12, OpenCV 3.3.0

Python 实现

import numpy as np
import cv2

sdThresh = 10
font = cv2.FONT_HERSHEY_SIMPLEX

def distMap(frame1, frame2):
    """outputs pythagorean distance between two frames"""
    frame1_32 = np.float32(frame1)
    frame2_32 = np.float32(frame2)
    diff32 = frame1_32 - frame2_32
    norm32 = np.sqrt(diff32[:,:,0]**2 + diff32[:,:,1]**2 + \
             diff32[:,:,2]**2)/np.sqrt(255**2 + 255**2 + 255**2)
    dist = np.uint8(norm32*255)
    return dist

cv2.namedWindow('frame')
cv2.namedWindow('dist')

#capture video stream from camera source. 0 refers to first camera, 1 referes to 2nd and so on.
cap = cv2.VideoCapture(0)

_, frame1 = cap.read()
_, frame2 = cap.read()

facecount = 0
while(True):
    _, frame3 = cap.read()
    rows, cols, _ = np.shape(frame3)
    cv2.imshow('dist', frame3)
    dist = distMap(frame1, frame3)

    frame1 = frame2
    frame2 = frame3

    # apply Gaussian smoothing
    mod = cv2.GaussianBlur(dist, (9,9), 0)

    # apply thresholding
    _, thresh = cv2.threshold(mod, 100, 255, 0)

    # calculate st dev test
    _, stDev = cv2.meanStdDev(mod)

    cv2.imshow('dist', mod)
    cv2.putText(frame2, "Standard Deviation - {}".format(round(stDev[0][0],0)), \
                (70, 70), font, 1, (255, 0, 255), 1, cv2.LINE_AA)
    if stDev > sdThresh:
            print("Motion detected.. Do something!!!");

    cv2.imshow('frame', frame2)
    if cv2.waitKey(1) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

C++ 实现

复制下面的代码,保存为 motion.cpp,运行下面的编译命令即可

g++ motion.cpp -o motion `pkg-config --cflags --libs opencv`
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include"omp.h"

using namespace cv;
#define MOTION_THRESH 10

void distMap(const Mat &a, const Mat &b, Mat &out){
    #pragma omp parallel
    for(int y = 0; y < a.rows; ++y){
        for(int x = 0; x < a.cols; ++x){
            int summary = 0;
            for(int z = 0; z < a.dims; ++z){
                summary += pow(a.at<Vec3b>(y, x)[z] - b.at<Vec3b>(y, x)[z], 2);
            }
            out.at<uchar>(y, x) = (int) (255.0 * sqrt(summary) / sqrt(3 * pow(255, 2)));
        }
    }
}


int main(int argc, char **argv){
    printf("=========== initializing ==========\n");

    int device = 0;
    int motion_count = 0;

    if(argc == 2) {
        device = atoi(argv[1]);
    }

    printf("device id %d\n", device);

    VideoCapture myCamera(device);

    myCamera.set(CV_CAP_PROP_FRAME_WIDTH, 640);
    myCamera.set(CV_CAP_PROP_FRAME_HEIGHT, 480);

    if (!myCamera.isOpened()){
        printf("cannot open camera\n");
        return 0;
    }else{
        printf("%s\n", "===========start camera==========");
    }

    Mat preVideoFrame, curVideoFrame, nextVideoFrame;

    for(int i = 0; i < 5; i++) {
        myCamera >> preVideoFrame;
    }

    myCamera >> preVideoFrame;
    myCamera >> curVideoFrame;


    Mat dist(preVideoFrame.rows, preVideoFrame.cols, CV_8UC1);
    Mat blurDist(preVideoFrame.rows, preVideoFrame.cols, CV_8UC1);
    Mat threDist(preVideoFrame.rows, preVideoFrame.cols, CV_8UC1);
    Mat meanDist(preVideoFrame.rows, preVideoFrame.cols, CV_8UC1);
    Mat stdDist(1, 1, CV_8UC1);

    char text[100] = {0};

    int key = 0;
    while (key != 27){
        myCamera >> nextVideoFrame;

        // key = waitKey(1);
        // continue;

        if (!preVideoFrame.empty() && !curVideoFrame.empty() && !nextVideoFrame.empty()){
            distMap(preVideoFrame, nextVideoFrame, dist);

            curVideoFrame.copyTo(preVideoFrame);
            nextVideoFrame.copyTo(curVideoFrame);

            blur(dist, blurDist, Size(3, 3));

            threshold(blurDist, threDist, 100, 255, THRESH_BINARY);

            meanStdDev(threDist, meanDist, stdDist);

            sprintf(text, "Standard Deviation - %d", stdDist.at<uchar>(0, 0));

            cv::putText(curVideoFrame, text, Point(70, 70), FONT_HERSHEY_SIMPLEX, 
                        1, (255, 0, 255), 1, LINE_AA);

            if(stdDist.at<uchar>(0, 0) > MOTION_THRESH) {
                printf("%d motion detected\r", stdDist.at<uchar>(0, 0));
                fflush(stdout);
            }

            imshow("distMap", blurDist);
            imshow("preview", curVideoFrame);

        }

        key = waitKey(1);
    }

    myCamera.release();
    printf("%s\n", "===========release camera==========");

    return 0;
}

参考内容

  1. Motion detection using OpenCV
OpenCV 使用光流法检测物体运动 阅读详情

相关推荐

【opencv】基于opencv实现运动目标检测之帧差法

帧差法是背景减图法中的一种,只不过是帧差法不需要建模,因为它的背景模型就是上一帧的图,所以速度非常快,另外帧差法对缓慢变换的光照不是很敏感,所以其用途还是有的。             代码如下: #include #include "cv.h" #include "opencv2/opencv.hpp" using namespace std; using namespace cv;

Mr_EvanChen的Blog 6147

【opencv学习之四十二】简单运动检测

视频运动检测基本思想是进行每一帧对比,检测不同然后得出是否运动,一般分为两种,背景法和差帧法;背景法是:将一幅图作为背景,让后和每一帧对比;缺点是一开始存入的背景可能随光照变法而造成错误,但是可以用在光照环境稳定的地方,优点是可以检测之前背景没有的景象;差帧法是:将前一帧和后一帧进行对比;缺点是无法对运动后突然又静止的景象进行识别,优点是光照不影响;实例背景法://////////////////...

abcvincent的博客 1787

python_opencv 运动检测视频处理

python_opencv 运动检测视频处理本文代码是做一个基本的运动检测代码如下:遇到的问题及解决办法: 本文代码是做一个基本的运动检测 借鉴别人的代码并做了小小的扩展,实现了自己需要的功能,并将实现过程中遇到的问题及解决办法做了总结,特此分享给大家, 代码如下: import cv2 import numpy as np import os import os.path list1 = ...

张益达的博客 3936

利用摄像头实现人员活动检测(python+openCV)

1.前言        最近在做个机器人比赛,其中一项要求是让机器人实现对是否有人员活动的检测,所以就先拿PC端写一下,准备移植到机器人的树莓派。2.工具               工具还是简单的python+视觉模块openCV,代码量也比较少。很简单就可以实现3.人员检测的原理      从图书馆借了一本《特征提取与图像处理(第二版)》,是Mark S.Nixon和Alberto S.Agu...

qq_35624030的博客 7719

C++基于OpenCV实现实时监控和运动检测记录

C++基于OpenCV实现实时监控和运动检测记录

qq_43680030的博客 2603

OpenCV实现静止背景下运动目标的检测

这两天从零开始学习视频流中运动目标检测的方法,有点心得体会,写点东西跟大家共享,同时提出我的几个疑问,期望能够共同讨论进步。     本文主要面向和我一样的图像处理初学者,先从原理上把整个检测过程走通,然后再逐步提高性能。     1、关于运动目标检测的方法总结     查阅了相关的文献,目前能够实现运动物体检测的方法主要有以下几种:     1)背景差分法:能完整快速地分割出运动图像

奋斗斌斌的专栏 3万+

openCV学习笔记十七:摄像头中运动物体检测

我们知道视频都是由一帧一帧图像构成的,利用帧差法,相邻两三帧图像像素之间的差异性判断是否有运动目标。 基本步骤 相邻帧相减------阈值处理------去除噪声(腐蚀滤波)------膨胀连通------查找轮廓------外接矩形 // A code block var foo = 'bar'; 帧差法代码如下: #include &lt;cv.h&gt; #include &lt;high...

楼阁之束的博客 5455

基于ROS+kinect+opencv的运动物体检测

前段时间学习了基于opencv的运动物体检测,现将学习经验分享如下。 一、原理 这次的运动物体检测用到了古月居大侠的代码然后稍加修改了一下,但整体功能没有太大变化。基于opencv的运动物体检测的原理为:先接收kinect发布的图像话题,将此接收到的RGB图像转换为opencv可处理的灰度图像,经过高斯滤波函数进行图像平滑处理后,获取该灰度图和前一张灰度图的灰度差值,若没检测到运动物体,则灰度...

qq_29716885的博客 1704

OpenCV:运动模板检测

#include #include #include #include #include #include // 不同的跟踪参数 const double MHI_DURATION = 0.5; const double MAX_TIME_DELTA = 0.5; const double MIN_TIME_DELTA = 0.05; // 用于运动检测的循环帧数,与机器速度及FP

yangchuankai's blog 3769

OpenCV之帧差法检测运动目标

今天的目标是用OpenCV实现对运动目标的检测,这里选用三帧帧差法。代码如下:

DY580C的专栏 5191

Opencv项目实战:18 人体姿态检测

mediapipe中有人体姿态检测的功能,今天我们就将实现最最基础的人体姿态估计项目,它的应用还是有很多的,比如:AI锻炼检测标准、老人跌倒检测等,这些方面其实已经有了很多的参考资料了,当然在我知道的当中用yolo的倒是挺多的。那么今天我们将会通过人物跳舞的视频进行一个姿态的检测。本次项目是按照mediapipe提供的人体姿态估计的功能实现的项目,非常的基础和简单,后面如果我有更好的点子会继续更新这部分内容。

m0_62919535的博客 7672

opencv3 目标运动检测

基本的运动检测

淮南草的博客 7382

使用 ESP32 CAM 和 OpenCV 的运动检测

使用 ESP32 摄像头和 Python 的红灯绿灯游戏

DT程序员的博客 2137

[C++]OpenCV基于帧差法的运动检测

最简单的帧差法就是二帧差分法,将视频流中的前后两帧图像转换为灰度图像,再经过高斯模糊消除噪声干扰,然后将两帧图像进行相减操作得到两帧图像之间的差异区域,再对差异图像进行二值分割把差异区域作为前景、不变区域作为背景,并且进行开运算操作来消除一些微小干扰。可见三帧差分法的性能是要优于二帧差分法的,而且由于帧差法本身的运算规模并不算特别庞大,所以运行速度还是比较理想的,对于二帧差和三帧差之间的运行速度虽然有差距,但是在视频播放过程中均没有出现明显的卡顿现象。

FL1768317420的博客 1812

OpenCV实现运动人体摔倒检测项目

随着科技的发展,越来越多的智能监控系统开始关注于对人体运动行为的理解与分析。摔倒检测技术,作为其中的一项重要应用,对于老年人监护、公共场所安全管理等领域具有重要意义。其主要目标是通过分析视频流中的运动人体,识别出摔倒事件,及时发出警报或通知相关人员。本章将从摔倒检测技术的原理、应用场景、以及在日常生活中的重要性等多个方面进行概述,为您揭开摔倒检测技术的神秘面纱。OpenCV是一个开源的计算机视觉库,提供超过2500个优化的算法,这些算法涵盖从图像处理到计算机视觉的各个方面。

weixin_30995917的博客 796

Kinect2.0+Opencv人体骨骼捕捉及绘制VisualStudio2015工程文件

使用Kinect2.0获取人体骨骼,并使用openCV实时绘制,里面为VisualStudio2015工程文件,配置好Kinect开发环境可直接用VS2015打开并运行

python opencv 运动目标检测_opencv 运动目标检测 | 学步园

请注意你要安装opencv,复制代码后要配置opencv环境,然后找个视频把代码中路径改为你视频路径。#include "cv.h"#include "highgui.h"#include #include #include #include // various tracking parameters (in seconds) //跟踪的参数(单位为秒)const double MHI_DURA...

weixin_39962199的博客 477

游戏开发实战:5种AOI算法对比(九宫格 vs 灯塔 vs 十字链表)

本文深入对比了游戏开发中五种主流AOI算法(九宫格、灯塔、十字链表等)的性能与适用场景,帮助开发者根据项目规模选择最优解决方案。通过详细的技术分析和实战数据,揭示不同算法在万人同屏等极端场景下的表现差异,为MMORPG等大型多人在线游戏提供关键性能优化指南。

weixin_29268385的博客 474

Python与OpenCV(一)——基于帧差法的运动目标检测程序分析

OpenCV提供了强大的图像处理功能,与Python的结合堪称完美。。。 这一次,我们来试一下运动目标的检测与跟踪。。。 先上源码: 源码呈现 源码是从网上找的,原作者写的很精炼,分析的也好,就是没有逐句分析,所以我们先上源码,再分析: import cv2 import numpy as np camera = cv2.VideoCapture(0) if (camera.isOpened()): print('摄像头成功打开') else: print('摄像头未打开') size = (i

drippingstone的博客 1万+

手把手教你用LDR9201芯片DIY高性能Type-C耳机转接头(附电路图)

本文详细介绍了基于LDR9201芯片DIY高性能Type-C耳机转接头的完整实战教程。从芯片选型、电路设计、元器件采购到焊接调试,手把手指导如何打造一个免驱兼容、支持高解析度音频且可通过EEPROM深度定制功能的专属转接头。重点解析了LDR9201作为高度集成的USB音频控制器SoC的优势,并提供了核心电路图与配置指南,适合电子爱好者和硬件开发者实践。

jump7的博客 355

视频流推理的工程架构:YOLO模型如何做到单卡处理16路1080P实时流?

<think>我们只需要根据内容生成摘要,不超过150字。内容是关于YOLO模型单卡处理16路1080P实时流的技术分析,包括方案对比、架构设计等。摘要要简洁,突出关键点。</think>本文深度解析了YOLO模型单卡处理16路1080P实时流的技术方案,对比EagleEye、TensorRT+DeepStream、华为CANN及RK3588四条路线,重点介绍流水线架构、并发模型及显存优化,指出消费级显卡(如RTX 4090)即可实现高并发智能视觉分析。

2601_95807009的博客 162
上一篇: 安装MySQL出现1045错误
下一篇: 安装 OpenCV 以及 opencv_contrib
echo42
博客等级 码龄12年 11粉丝 5原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值