36-运动物体检测2(EmguCV学习)

帧差法Motion Detection(基于EmguCV实现) 帧差法,就是 result=currentFrame-previousFrame 阅读详情

Record

案例:
1、使用椭圆对运动物体轮廓进行拟合(略);
2、使用滤波方法去除噪声(略);
3、根据轮廓正外接矩形大小对轮廓进行筛选(略);
4、绘制物体的运动轨迹(done);
5、简单的车辆计数(done);

Code


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Emgu.CV;
using Emgu.CV.Util;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using Emgu.Util;
using System.Drawing;

namespace lesson36
{
    class Program
    {
        public static VectorOfPoint vcenterPoints = new VectorOfPoint();       //存储中心点集
        public static int carNum = 0;                                          //存储车的计数数目
        static void Main(string[] args)
        {
            //运动物体质心轨迹绘制
            //VideoCapture cap = new VideoCapture("man.avi");
            //if(!cap.IsOpened)
            //{
            //    Console.WriteLine("Open video failed..");
            //    return;
            //}
            //int count = 0;
            //Mat bgImg = new Mat();
            //Mat frame = new Mat();
            //while(true)
            //{
            //    cap.Read(frame);
            //    if(frame.IsEmpty)
            //    {
            //        Console.WriteLine("frame is empty..");
            //        break;
            //    }
            //    count++;
            //    if(count == 1)
            //    {
            //        bgImg = frame.Clone();  //背景差法
            //    }
            //    Mat result = MoveDetect(bgImg, frame);
            //    CvInvoke.Imshow("result", result);
            //    if (CvInvoke.WaitKey(50) == 27)
            //    {
            //        break;
            //    }
            //}

            ///车辆计数演示
            VideoCapture cap = new VideoCapture("car.avi");
            if(!cap.IsOpened)
            {
                Console.WriteLine("Open the video failed..");
                return;                   
            }
            Mat preframe = new Mat();
            Mat frame = new Mat();
            int count = 0;
            while (true)
            {
                cap.Read(frame);
                if(frame.IsEmpty)
                {
                    Console.WriteLine("frame is empty..");
                    break;
                }
                count++;
                if (count == 1)
                {
                    preframe = frame.Clone();
                }
                Mat result = MoveDetect4(preframe, frame);
                CvInvoke.Imshow("result", result);
                preframe = frame.Clone();       //更新前一帧

                if (CvInvoke.WaitKey(50) == 27)
                    break;
            }


        }


        static Mat MoveDetect4(Mat preframe,Mat frame)
        {
            Mat result = frame.Clone();
            Mat gray = new Mat();
            Mat gray2 = new Mat();
            CvInvoke.CvtColor(preframe, gray, ColorConversion.Bgr2Gray);
            CvInvoke.CvtColor(frame, gray2, ColorConversion.Bgr2Gray);
            Mat diff = new Mat();
            CvInvoke.AbsDiff(gray2, gray, diff);
            CvInvoke.Imshow("diff", diff);
            //转换为二值图
            CvInvoke.Threshold(diff, diff, 20, 255, ThresholdType.Binary);
            //滤波
            CvInvoke.MedianBlur(diff, diff, 17);
            //膨胀
            Mat element = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(21, 21), new Point(-1, -1));
            CvInvoke.Dilate(diff, diff, element, new Point(-1, -1), 1, BorderType.Default, new MCvScalar());
            CvInvoke.Imshow("dilate", diff);
            //计算轮廓
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            CvInvoke.FindContours(diff, contours, null, RetrType.External, ChainApproxMethod.ChainApproxNone);

            //对轮廓进行遍历,当轮廓经过特定位置时认为经过了检测线,计数变量+1
            for (int i = 0; i < contours.Size; i++)
            {
                Rectangle rect = CvInvoke.BoundingRectangle(contours[i]);
                if(rect.Width > 40 && rect.Width < 180 && 
                                      rect.Height > 40 && rect.Height < 180)        //对轮廓大小进行筛选
                {
                    //绘制出包含车辆的矩形
                    CvInvoke.Rectangle(result, rect, new MCvScalar(0, 255, 0), 2);
                    //当车辆质心Y方向在这个范围内时,车辆计数加1
                    if((rect.Y + rect.Height/2 - 1) >=138 && (rect.Y + rect.Height / 2 - 1 ) <= 142)
                    {
                        carNum++;
                        //车辆经过时绘制显示线示意一下
                        CvInvoke.Line(result, new Point(0, 141), new Point(frame.Cols - 1, 142), new MCvScalar(0, 0, 255), 3);
                        CvInvoke.Circle(result, new Point((int)(rect.X + rect.Width / 2), 142), 5, new MCvScalar(0, 255, 255), -1);
                    }
                }
            }
            //绘制扫描线
            CvInvoke.Line(result, new Point(0, 141), new Point(frame.Cols - 1, 141), new MCvScalar(0, 0, 255), 1);
            string strNum = string.Format("CarNUm={0}", carNum);    //格式化字符串
            CvInvoke.PutText(result, strNum, new Point(10, 25), FontFace.HersheyComplex, 1.2, new MCvScalar(0, 255, 0), 2);
            return result;
        }

        static Mat MoveDetect(Mat bgImg,Mat fgImg)
        {
            Mat result = fgImg.Clone();
            Mat gray = new Mat();
            Mat gray2 = new Mat();
            CvInvoke.CvtColor(bgImg, gray, ColorConversion.Bgr2Gray);
            CvInvoke.CvtColor(fgImg, gray2, ColorConversion.Bgr2Gray);
            //做差
            Mat diff = new Mat();
            CvInvoke.AbsDiff(gray2, gray, diff);
            CvInvoke.Imshow("diff", diff);
            //二值化
            CvInvoke.Threshold(diff, diff, 45, 255, ThresholdType.Binary);
            CvInvoke.Imshow("threshold", diff);
            //滤波膨胀
            CvInvoke.MedianBlur(diff, diff, 5);
            Mat element = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(13, 13), new Point(-1, -1));
            CvInvoke.Dilate(diff, diff, element, new Point(-1, -1), 1, BorderType.Default, new MCvScalar());
            CvInvoke.Imshow("dilate", diff);

            //计算轮廓
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            CvInvoke.FindContours(diff, contours, null, RetrType.External, ChainApproxMethod.ChainApproxNone);

            for(int i = 0; i < contours.Size; i++)
            {
                Rectangle rect = CvInvoke.BoundingRectangle(contours[i]);
                if(rect.Width > 10 && rect.Height >10)          //轮廓筛选
                {
                    RotatedRect ellipse = CvInvoke.MinAreaRect(contours[i]);
                    //绘制最小外接椭圆
                    CvInvoke.Ellipse(result, new Point((int)ellipse.Center.X, (int)ellipse.Center.Y),
                                     new Size((int)ellipse.Size.Width/2, (int)ellipse.Size.Height/2), ellipse.Angle,
                                     0, 360, new MCvScalar(0, 255, 0), 2);
                    Point ptCenter = new Point((int)ellipse.Center.X, (int)ellipse.Center.Y);
                    Point[] pts = { ptCenter };
                    vcenterPoints.Push(pts);
                    if(vcenterPoints.Size > 1)   //点集中至少有两个点
                    {
                        for(int j = 0; j < vcenterPoints.Size-1; j++)
                        {
                            CvInvoke.Line(result, vcenterPoints[j], vcenterPoints[j + 1], new MCvScalar(255, 0, 0), 2);
                        }
                    }
                    CvInvoke.Circle(result, ptCenter, 3, new MCvScalar(0, 0, 255), -1);
                }
            }
            return result;
        }
    }
}


效果

1、物体运动轨迹绘制:

在这里插入图片描述

2、简单的车辆计数:

在这里插入图片描述
在这里插入图片描述

利用Emgu cv3.4制作视频监控,自己做行车记录一样 主要需要用到Capture类,VideoWriter,对象构造函数如下: public Capture(int camIndex);----用于初始化摄像头。 public VideoWriter(string fileName, int fps, Size size, bool isColor);-----建立视频生产文件。 主要用到函数: public virtual bool Ret... 阅读详情

相关推荐

c#视觉应用开发中如何在C#中进行运动检测?

这个示例展示了一个简单的运动检测应用,使用背景减除器来检测运动。你可以根据需要进一步优化和扩展,例如加入运动区域的轮廓检测、跟踪等功能。当然,接下来我们可以进一步优化和扩展这个运动检测应用。通过这些改进,你可以创建一个更加复杂和可靠的运动检测和跟踪系统。根据需求,你还可以加入更多的特性,例如物体分类、轨迹预测、警报系统等。希望这些示例能帮助你在C#中实现运动检测应用。当然,接下来我们可以继续扩展功能,加入更多的特性以实现一个更复杂和可靠的运动检测和跟踪系统。

zhangzhechun的专栏 279

CEmguCV 运动检测实例代码

C#EmguCV 运动检测实例代码 去发现同类优质开源项目:https://gitcode.com/ 本项目提供了C#版的OpenCV(EMguCV)运动检测的实例代码。通过本代码,开发者可以学习如何使用EMguCV库在C#环境中实现运动检测功能。以下是代码和注释的详细介绍: 资源文件简介 标题:C#EmguCV 运动检测 描述:C#版OpenCV--EMguCV,实现运动检测实例,基本代码,完...

gitblog_06777的博客 411

灰度世界算法:自动白平衡的经典实现

灰度世界算法是计算机视觉和数字图像处理领域中最经典且最基础的白平衡算法(Auto White Balance, AWB)。其主要功能是修正由于光照色温差异造成的图像色彩偏差(例如室内黄光导致的偏黄或阴天环境下的偏蓝现象),使图像色彩更贴近人眼观察到的真实效果。

工业上位机开发工程师,专注C#底层算法与工控仪器开发。从零手写信号滤波、曲线拟合、机器视觉、排序与密码学哈希,纯原生实现零第三方库,附数学推导与可编译源码,可移植STM32/PLC。 758

EmgnCv进行轮廓寻找和计算物体凸包

一、轮廓寻找 用的是FindContours函数,在CvInvoke中 不过需要用到这个VectorOfVectorOfPoint,来代替c++中的Vector 还有就是FindContours函数中的第三个参数hierarchy,不知道作用是什么,填入的只要是符合IOutputArray类型的都可以运行 代码:using System; using System.Collections.G

k 1万+

EmguCV:C#中应用OpenCV的综合指南

EmguCV是一个基于开源计算机视觉库OpenCV的跨平台.NET封装库,它允许开发人员使用C#和其他.NET兼容语言来开发计算机视觉应用程序。EmguCV不仅保留了OpenCV的核心功能,还加入了跨平台支持,使其能够运行在Windows、Linux甚至是MacOS系统上。颜色空间是指使用不同的颜色表示方法来描述颜色。在图像处理中,常见的颜色空间有RGB、HSV、YCbCr等。RGB是最常用的颜色空间,它由红(R)、绿(G)、蓝(B)三个颜色通道组成。

weixin_35950531的博客 683

C# OpenCV图片识别落地的四大硬坎:环境、内存、预处理与业务耦合

图片识别是计算机视觉的基础能力,其核心在于将图像数据转化为可计算的结构化信息。OpenCV作为最成熟的开源图像处理库,提供了从滤波、边缘检测到深度学习推理的全栈能力;而C#凭借.NET平台的稳定性与工业软件生态优势,成为上位机、工控系统和边缘设备的首选开发语言。二者结合的技术价值在于兼顾开发效率与生产可靠性,但真实落地时需直面ABI兼容性、托管/非托管内存协同、光照与噪声鲁棒性预处理,以及识别逻辑与业务规则的深度咬合。本文聚焦C#调用OpenCV进行图片识别的工程实践,深入解析DLL加载失败、Mat内存泄漏

weixin_32642109的博客 250

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

4 添加项目引用Emgu.CV.dll、Emgu.CV.Platform.NetFramework.dll、System.Drawing.dll和System.Runtime.InteropServices.RuntimeInformation.dll。2 把win-x64目录的native目录下的文件全部拷贝到项目的运行目录Debug目录下。我这个是失败品,效果太差了,黑色的车压根就检测不到,后面的就不做了,仅作记录。想要获取到运动中的车辆,需要比较两帧视频的图片,然后做减法运算。

zxy13826134783的博客 930

C#EmguCV 运动检测

C#版OpenCV--EMguCV,实现运动检测实例,基本代码,完美注释

EmguCV学习——简单算法 差分与高斯

公司项目需要检测运动物体,我对opencv也没啥研究,google了好久看了好多方法,最简单的就是差分与高斯背景建模了。 旁边搞c++的同事正在搞更nb的算法,等出来了 我再转成C#版的分享。 先看差分 1 //移动窗口       [System.Runtime.InteropServices.DllImportAttribute("ope...

weixin_30569153的博客 231

EmguCV播放视频及动目标检测

本案例可以利用C#和EmguCV播放文件夹和摄像头中的视频,代码运行完美无误,可以简单实施视频运动目标检测与跟踪,欢迎交流

图片边界矢量化-地理配准

无地理和投影信息的JPG图片,通过ArcGIS进行地理配准(Georeferencing)完成数字化边界。

u012727861的博客 1904

Emgu.CV训练自己的hog特征,可实现任意物体的检测

emgu.cv自行训练HOG,目前最详细的一篇C#资料

技术+管理+经验+沟通+人品=>合格的项目管理者 1万+

(一)DaVinci Developer AutoSAR工具 如何新建SWC、Component、RTE工程,超级详细步骤,赚到

​ 1,创建SWC,第一步需要创建一个App组件类型,首先点击Object Brower菜单,然后左键Application Component Types 选项,然后右键New Application Component Type,组件类型的作用是来后续实例一个Compoent 2、 Properties 选项卡中Nane中输入Type的名字,注意根据规范命名规则已CtAp开头,其他默认就好 ​

weixin_42602687的博客 3574

Emgu安装配置及使用

前言:项目需要,需使用图像处理来完成机械臂从运动的皮带上抓取物体的功能,所以又重拾视觉与图像处理内容。 内容:Emgu是OpenCV的一个跨平台的.NET封装,结构如下图所示: 下载地址:http://sourceforge.net/projects/emgucv/,下载最新版本的就好。 运行下载的EXE文件,完成后添加环境变量:我的电脑->属性-...

anqu6354的博客 316

告别U盘!在Ubuntu 22.04上从零搭建PXE网络装机服务器(支持UEFI/Legacy双启动)

本文详细介绍了在Ubuntu 22.04上搭建PXE网络装机服务器的完整流程,支持UEFI/Legacy双启动模式。通过配置DHCP、TFTP和HTTP服务,实现无需U盘的高效批量系统部署,解决传统安装方式的介质依赖、版本控制和时间成本问题,显著提升机房维护和设备部署效率。

weixin_42569329的博客 248

Cadence IC618版图DRC验证License报错排查:从虚拟机网络配置到HOSTID的实战解析

本文详细解析了Cadence IC618版图设计中DRC验证License报错的排查方法,重点从虚拟机网络配置到HOSTID获取的实战经验。通过对比ifconfig与ip add命令的差异,提供了正确的HOSTID获取方式及License文件修改技巧,帮助工程师快速解决IC618环境下的DRC验证问题。

weixin_30823001的博客 677

目标跟踪学习笔记_1(opencv中meanshift和camshift例子的应用)

在这一节中,主要讲目标跟踪的一个重要的算法Camshift,因为它是连续自使用的meanShift,所以这2个函数opencv中都有,且都很重要。为了让大家先达到一个感性认识。这节主要是看懂

CHCH998的博客 444

gem5 prefetcher

最近在gem5上做预取实验,添加自己的预取算法,这里采用hardware stream prefetcher , 修改了几个bug才给实验调试通过,发文记录下实验过程。 gem5上添加自己的预取算法步骤: (1)路径gem5-master/configs/common/Caches.py下,开启预取:class L1Cache(Cache): assoc = 2 tag_late

编程邦 3843

EmguCV学习笔记 C# 7.2 特征点检测

SIFT算法是一种基于尺度空间极值检测和高斯差分图像描述子的算法,具有较高的特征检测精度和描述子匹配准确性,它可以在不同尺度和旋转角度下检测和描述图像中的特征点,由于其良好的尺度不变性和旋转不变性,被广泛应用于计算机视觉领域。在使用SIFT算法提取特征描述子时,特征描述子保存在一个Mat类型变量中,该Mat的大小是“关键点的数量×128”,对应Mat的“行×列”,每个关键点为一行,128表示每个特征描述子包含128个数值,这些数值表示了关键点周围区域的特征信息,可以用于描述和区分不同的关键点。

学习微软 .net 技术开发 2085

大厂嵌入式面试常考八股文及算法

1.指向已被释放或无效的内存地址的指针是野指针。互斥锁是一种用于线程同步的机制,用于确保同一时间只有一个线程访问共享资源。多态是面向对象编程中的一种特性,它允许以一种统一的方式处理不同类型的对象,通过相同的接口可以表现出不同的行为。大小端(Endian)指的是在计算机存储和处理多字节数据时,字节的存储顺序。大端序(Big Endian):高位字节存储在低地址,低位字节存储在高地址。类似于将数字的高位放在左边,低位放在右边的表示方式。例如整数值0x12345678在内存中按照大端序排列为。

谢谢大家的关注 6152

海洋CMS admin_notify.php 远程代码执行漏洞复现(CVE-2024-30565)

海洋CMS admin_notify.php 接口处存在远程代码执行漏洞,经过身份验证的远程攻击者可利用该漏洞执行任意代码,写入后门文件,进而控制整个web服务器。

0xSec 2713

c#结合emgucv进行人脸检测_通过ZAT结合机器学习进行威胁检测

机器学习概述在机器学习中我们针对安全数据的处理显得异常重要,针对不同的攻击类型数据我们需要选择合适的算法但是大体过程都是分为以下几个步骤:获取数据特征抽取特征预处理特征降维模型训练模型评估通过zat处理zeek全流量日志数据今天这篇文章主要是介绍通过zat处理zeek的全流量数据的分析方法。zeek是开源NIDS入侵检测引擎,目前使用较多的是互联网公司的风控业务。zeek中提供了一种供z...

weixin_39624733的博客 211

程序化广告ADX系统架构设计与实现

摘要: 本文详细介绍了程序化广告交易平台(ADX)的系统架构设计与实现。ADX作为连接广告主与媒体的核心平台,采用基于腾讯云和阿里云的微服务架构,包含网络基础设施、负载均衡、消息处理、核心业务服务和多级数据存储等层次。重点解析了Kafka消息队列处理高并发广告请求、Redis实时统计关键指标等核心技术实现,并提供了Java代码示例展示广告请求处理、竞价流程等核心功能。该系统通过分层设计和分布式组件,实现了高性能、高可用的程序化广告交易能力。

私聊前往站内信:https://i.youkuaiyun.com/#/msg/chat/weixin_44976692 764

【 Emgu CV教程】1.1、Emgu CV 简介及使用

C#利用Emgu CV进行图像、视频处理的简单教程。

活宝的博客 1万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

35-运动物体检测1(EmguCV学习)

运动物体检测RecordCode效果 Record Code 效果

hello 1910

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Emgucv不完整图像分割试验(九)——运动追踪

越来越懒了,反正就是几个模型的using的库微微的有一点不一样,自己官网搜搜。 BackgroundSubtractorMOG2 bg_mog = null;//随便什么模型,大概有4个老的2个新的,都一样的写法。 Mat scr = new Mat();//更新输入图像。 Mat mask = new Mat();//运动检测输出图像。 ...

qq_26996385的博客 888

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

上一篇: 35-运动物体检测1(EmguCV学习)
下一篇: 37-简单人脸检测实例(EmguCV学习)
hellohake
博客等级 码龄10年 4543粉丝 108原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值