【C#】人脸识别 视频数据转图片数据
使用虹软人脸识别的开发过程中遇到了转换的问题
因为不会用C#直接打开摄像头,就只能用第三方dll。一开始用Aforge,后来发现有个问题,关闭摄像头老是陷入等待,所以抛弃了。前一阵子开始用封装了OpenCV的Emgu,一路走来也是N声叹息。
一、安装Emgu的叹息
一开始自己下载并安装了Emgu,然后各种测试,发现还需要这个那个的,最后发现直接安装一个EMGU.CV的NuGet包就OK了。
当然要打开视频,还需要引用System.ServiceModel。
二、获取视频用Emgu获取视频真心十分方便
1.定义两个变量
VideoCapture _VideoCapture;
Mat _Frame = new Mat();
2.初始化视频
_VideoCapture = new VideoCapture();
//_VideoCapture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameWidth, 1024); //设置宽度
//_VideoCapture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameHeight, 768);//设置高度
_VideoCapture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.Fps, 10);//设置每秒钟的帧数
_VideoCapture.Start();
_VideoCapture.ImageGrabbed += _VideoCapture_ImageGrabbed; //视频事件
3.视频显示
private void _VideoCapture_ImageGrabbed(object sender, EventArgs e)
{
_VideoCapture.Retrieve(_Frame, 1);
this.pictureBox1.Image = _Frame.Bitmap; //很神奇的pictureBox,居然不在UI线程也能显示
}
4.获取当前帧
用于人脸比对,一般在另外一个线程
Mat curFrame=_VideoCapture.QueryFrame();
一切十分完美,就是_Frame.Bitmap似乎没有Dispose(后来发现Mat的地址是不变,不会发生内存泄漏),但运行起来也没问题。
三、人脸识别的叹息
看了一下,人脸识别需要Bitmap,方便
Mat curFrame=_VideoCapture.QueryFrame();
Bitmap bitmap=curFrame.Bitmap;
var bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
int width = (bitmap.Width + 3) / 4 * 4;
var bytesCount = bmpData.Height * width * 3;
IntPtr pImageData = Marshal.AllocCoTaskMem(bytesCount);
if (width == bitmap.Width)
CopyMemory(pImageData, bmpData.Scan0, bytesCount);
else
for (int i = 0; i < bitmap.Width; i++)
CopyMemory(IntPtr.Add(pImageData, i * width * 3), IntPtr.Add(bmpData.Scan0, i * bmpData.Stride), bmpData.Stride);
bitmap.UnlockBits(bmpData);
得到了ArcFace所需的图片数据pImageData,测试一下挺好,能运行。时间一长,报错了:“试读取或写入受保护的内存。这通常指示其他内存已损坏。”
估计人脸识别的线程和显示视频的线程冲突了,查看了Emgu的源代码,发现QueryFrame就是封装了Retrieve。
好吧,克隆一下,Bitmap bitmap=(Bitmap)curFrame.Bitmap.Clone();问题依旧!查看地址发现Clone没卵用!
四、最终解决的办法
研究了Mat这个东东,发现GetData()就能返回图片数据,而且不会冲突,最后写成:
1.定义
IntPtr _PImageData;
int _ImageWidth,_ImageHeight,_ImageSize;
2.初始化
_ImageWidth=_VideoCapture.Width;
_ImageHeight=_VideoCapture.Height;
_ImageSize = _VideoCapture.Width * _VideoCapture.Height * 3;
_PImageData = Marshal.AllocCoTaskMem(_ImageSize);
3.转换
Marshal.Copy(_Frame.GetData(), 0, _PImageData, _ImageSize);
ASFDetectFaces(pEngine,_ImageWidth, _ImageHeight,513,_PImageData, out var faceInfo);
...
一切变得如此简单,长叹一声!
五、其他
1.视频图片的宽度一般是4的倍数,所以上述方式肯定没问题。
2.经常有人问如何获取网络摄像头、ip摄像头的图像,其实就是
videoCapture = new VideoCapture("string filename");
如某tplink的IP摄像头的filename是这样的"rtsp://admin:admin@192.168.0.159/stream1",格式是rstp://用户名:密码@ip地址/...
各位C#的亲,你们怎么转换的?
【C#】人脸识别 视频数据转图片数据的更多相关文章
- jQuery 人脸识别插件,支持图片和视频
jQuery Face Detection 是一款人脸检测插件,能够检测到图片,视频和画布中的人脸坐标.它跟踪人脸并输出人脸模型的坐标位置为一个数组.我们相信,面部识别技术能够给我们的 Web 应用带 ...
- 基于安卓高仿how-old.net实现人脸识别估算年龄与性别
前几段微软推出的大数据人脸识别年龄应用how-old.net在微博火了一把,它可以通过照片快速获得照片上人物的年龄,系统会对瞳孔.眼角.鼻子等27个“面部地标点"展开分析,进而得出你的“颜龄 ...
- Android 用虹软SDK做人脸识别
人脸识别第三方sdk比较多,但是大多都是收费的或者限制次数什么的,虹软的效果还不错,全免费也不需要联网 V1.2版本使用和快速集成:https://www.jianshu.com/p/8dee89ec ...
- 技能节-AI人脸识别
我们收到技能节项目的通知是在两周之前,项目要求做个人脸评分系统. 两周时间写一个"人脸评分系统",好像时间比较紧了,还好我们完成了~这个项目是将摄像头捕获到的包含人脸的图像传输到百 ...
- facenet 人脸识别(二)——创建人脸库搭建人脸识别系统
搭建人脸库 选择的方式是从百度下载明星照片 照片下载,downloadImageByBaidu.py # coding=utf-8 """ 爬取百度图片的高清原图 &qu ...
- 3D动态人脸识别技术分析——世纪晟人脸识别实现三维人脸建模
- 目录 - 国内3D动态人脸识别现状概况 - 新形势下人脸识别技术发展潜力 - 基于深度学习的3D动态人脸识别技术分析 1. 非线性数据建模方法 2. 基于3D变形模型的人脸建模 - 案例结合——世 ...
- 6-9 Haar+adaboost人脸识别
我们重点分析了Haar特征的概念以及如何计算Haar特征,并介绍了Haar+Adaboost分类器它们的组合以及Adaboost分类器如何使用和训练.这节课我们将通过代码来实现一下Haar+Adabo ...
- python使用matplotlib画图,jieba分词、词云、selenuium、图片、音频、视频、文字识别、人脸识别
一.使用matplotlib画图 关注公众号"轻松学编程"了解更多. 使用matplotlib画柱形图 import matplotlib from matplotlib impo ...
- 基于Python3.7和opencv的人脸识别(含数据收集,模型训练)
前言 第一次写博客,有点紧张和兴奋.废话不多说,直接进入正题.如果你渴望使你的电脑能够进行人脸识别:如果你不想了解什么c++.底层算法:如果你也不想买什么树莓派,安装什么几个G的opencv:如果你和 ...
随机推荐
- 手把手教你创建私有podspec
本文来自 网易云社区 . CocoaPods是iOS非常好用的类库管理工具,可以非常方便的管理和更新项目中使用到的第三方库,以及将自己项目中的公共组件交由它管理. 工作中比较常用到的是通过CocoaP ...
- webpack4+Vue搭建自己的Vue-cli
前言 最近在看webpack4,深感知识浅薄,这两天也一直在思考cli的配置,借助一些别人的实践,尝试自己搭建vue的项目,这里使用webpack4版本,之前我在网上查找别人的vue项目搭建,但是都是 ...
- JavaScript入门学习(0)相关 软件工具
JavaScript本地脚本编辑工具(1st JavaScript Editor Pro ) 必要设置 https://pan.baidu.com/s/1XoaNA9o0qt2eJfLgoZ5 ...
- window7下 cmd命令行 Mysql导出表结构 + 表数据
命令格式 mysqldump -uroot -p 密码 库名 > 自定义路径/库名.sql
- 树莓派3B+学习笔记:11、查看硬件信息
1.查看CPU信息 cat /proc/cpuinfo 查看最后三行 如果只想查看最后三行,也可使用这个命令 /proc/cpuinfo lscpu 2.查看树莓派型号 cat /proc/devic ...
- 树莓3B+_apt-get update && apt-get upgrade
在Windows下安装软件,我们只需要有EXE文件,然后双击,下一步直接OK就可以了.但在LINUX下,不是这样的.每个LINUX的发行版,都会维护一个自己的软件仓库,我们常用的几乎所有软件都在这里面 ...
- Python学习 :多线程 --- 锁
多线程 什么是锁? - 锁通常被用来实现对共享资源的同步访问. - 为每一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其它线程已经获得了该锁,则当前线 ...
- 20155323 2016-2017-2 《Java程序设计》第一周学习总结
20155323 2016-2017-2 <Java程序设计>第一周学习总结 1.浏览教材,根据自己的理解每章提出一个问题 第一章:既然JDK本身附有一个JRE,那么JRE和JDK的区别在 ...
- 深入理解redis复制原理
原文:深入理解redis复制原理 1.复制过程 2.数据间的同步 3.全量复制 4.部分复制 5.心跳 6.异步复制 1.复制过程 从节点执行 slaveof 命令. 从节点只是保存了 slaveof ...
- BZOJ1010_玩具装箱toy_KEY
题目传送门 这道题可以很快想到暴力DP的做法: f[i]=min(f[i],f[j]+(C[i]-C[j]+i-j--L)^); 但是数据范围有50000,这就需要用斜率优化了. 我们设S[i]=C[ ...