当前位置:
首页 > Python基础教程 >
-
C#教程之C# 虹软SDK视频人脸识别和注册(2)
string FaceAppId = "BKgqTWQPQQbomfqvyd2VJzTbzo5C4T5w4tzgN3GL6euK";
/// <summary>
/// 虹软SDK人脸跟踪的Key
/// </summary>
const string FaceTraceKey = "2Yqm2EcsJyBbJjSrirPSNoyHDRKCrS53XgUDeRRxtKyR";
/// <summary>
/// 虹软SDK人脸检测的Key
/// </summary>
const string FaceDetectKey = "2Yqm2EcsJyBbJjSrirPSNoyQNpaSJz19noCteLQ88SoG";
/// <summary>
/// 虹软SDK人脸比对的Key
/// </summary>
const string FaceMatchKey = "2Yqm2EcsJyBbJjSrirPSNoyu2Rd4j1ydfwxwFX9vPmtY";
/// <summary>
/// 虹软SDK年龄识别的Key
/// </summary>
const string FaceAgeKey = "2Yqm2EcsJyBbJjSrirPSNoz9ME9R4xnKU9yecD8Axu1D";
/// <summary>
/// 虹软SDK性别识别的Key
/// </summary>
const string FaceGenderKey = "2Yqm2EcsJyBbJjSrirPSNozGWdQedYzhEUMw5FBegKVR";
/// <summary>
/// 缓存大小
/// </summary>
const int BufferSize = 40 * 1024 * 1024;
/// <summary>
/// 人脸跟踪的缓存
/// </summary>
//byte[] _FaceTraceBuffer = new byte[BufferSize];
/// <summary>
/// 人脸检测的缓存
/// </summary>
byte[] _FaceDetectBuffer = new byte[BufferSize];
/// <summary>
/// 人脸比对的缓存
/// </summary>
byte[] _FaceMatchBuffer = new byte[BufferSize];
/// <summary>
/// 年龄识别的缓存
/// </summary>
//byte[] _FaceAgeBuffer = new byte[BufferSize];
/// <summary>
/// 性别识别的缓存
/// </summary>
//byte[] _FaceGenderBuffer = new byte[BufferSize];
/// <summary>
/// 人脸跟踪的引擎
/// </summary>
//IntPtr _FaceTraceEnginer = IntPtr.Zero;
/// <summary>
/// 人脸检测的引擎
/// </summary>
IntPtr _FaceDetectEnginer = IntPtr.Zero;
/// <summary>
/// 人脸比对的引擎
/// </summary>
IntPtr _FaceMatchEngine = IntPtr.Zero;
/// <summary>
/// 年龄识别的引擎
/// </summary>
//IntPtr _FaceAgeEngine = IntPtr.Zero;
/// <summary>
/// 性别识别的引擎
/// </summary>
//IntPtr _FaceGenderEngine = IntPtr.Zero;
/// <summary>
/// 人脸库字典
/// </summary>
Face.FaceLib _FaceLib = new Face.FaceLib();
/// <summary>
/// 摄像头参数
/// </summary>
CameraPara _CameraPara = null;
double _RateW, _RateH;
private readonly ReaderWriterLockSlim _CacheLock = new ReaderWriterLockSlim();
Face.FaceResult _FaceResult = new Face.FaceResult();
System.Threading.CancellationTokenSource _CancellationTokenSource = new System.Threading.CancellationTokenSource();
bool _RegisterClicked = false;
byte[] _RegisterFeatureData = null;
#endregion
public Main()
{
InitializeComponent();
}
private void Main_Load(object sender, EventArgs e)
{
if (!Directory.Exists(FeaturePath))
Directory.CreateDirectory(FeaturePath);
foreach (var file in Directory.GetFiles(FeaturePath))
{
var info = new FileInfo(file);
var data = File.ReadAllBytes(file);
var faceModel = new Face.FaceModel
{
lFeatureSize = data.Length,
pbFeature = Marshal.AllocHGlobal(data.Length)
};
Marshal.Copy(data, 0, faceModel.pbFeature, data.Length);
_FaceLib.Items.Add(new Face.FaceLib.Item() { OrderId = 0, ID = info.Name.Replace(info.Extension, ""), FaceModel = faceModel });
}
_CameraPara = new Common.CameraPara();
if (!_CameraPara.HasVideoDevice)
{
MessageBox.Show("没有检测到摄像头");
this.Close();
return;
}
this.VideoPlayer.VideoSource = _CameraPara.VideoSource;
this.VideoPlayer.Start();
_RateH = 1.0 * this.VideoPlayer.Height / this._CameraPara.FrameHeight;
_RateW = 1.0 * this.VideoPlayer.Width / this._CameraPara.FrameWidth;
//var initResult = (Face.ErrorCode)Face.Trace.Init(FaceAppId, FaceTraceKey, _FaceTraceBuffer, BufferSize, out _FaceTraceEnginer, (int)Face.OrientPriority.Only0, 16, 1);
//if (initResult != Face.ErrorCode.Ok)
//{
// MessageBox.Show("初始化人脸跟踪引擎失败,错误代码为:" + initResult);
// this.Close();
// return;
//}
var initResult = (Face.ErrorCode)Face.Detect.Init(FaceAppId, FaceDetectKey, _FaceDetectBuffer, BufferSize, out _FaceDetectEnginer, (int)Face.OrientPriority.Only0, 16, 1);
if (initResult != Face.ErrorCode.Ok)
{
MessageBox.Show("初始化人脸检测引擎失败,错误代码为:" + initResult);
this.Close();
return;
}
initResult = (Face.ErrorCode)Face.Match.Init(FaceAppId, FaceMatchKey, _FaceMatchBuffer, BufferSize, out _FaceMatchEngine);
if (initResult != Face.ErrorCode.Ok)
{
MessageBox.Show("初始化人脸比对引擎失败,错误代码为:" + initResult);
this.Close();
return;
}
//initResult = (Face.ErrorCode)Face.Age.Init(FaceAppId, FaceAgeKey, _FaceAgeBuffer, BufferSize, out _FaceAgeEngine);
//if (initResult != Face.ErrorCode.Ok)
//{
// MessageBox.Show("初始化年龄识别引擎失败,错误代码为:" + initResult);
// this.Close();
// return;
//}
//initResult = (Face.ErrorCode)Face.Gender.Init(FaceAppId, FaceGenderKey, _FaceGenderBuffer, BufferSize, out _FaceGenderEngine);
//if (initResult != Face.ErrorCode.Ok)
//{
// MessageBox.Show("初始化性别识别引擎失败,错误代码为:" + initResult);
// this.Close();
// return;
//}
Task.Factory.StartNew(() =>
{
Task.Delay(1000).Wait();
while (!_CancellationTokenSource.IsCancellationRequested)
{
#region 200毫秒左右
MatchFrame();
#endregion
}
}, _CancellationTokenSource.Token);
}
private void Main_FormClosing(object sender, FormClosingEventArgs e)
{
if (_CameraPara.HasVideoDevice)
{
_CancellationTokenSource.Cancel();
System.Threading.Thread.Sleep(500);
this.VideoPlayer.Stop();
if (_FaceMatchEngine != IntPtr.Zero)
Face.Match.Close(_FaceMatchEngine);
//if (_FaceTraceEnginer != IntPtr.Zero)
// Face.Trace.Close(_FaceTraceEnginer);
if (_FaceDetectEnginer != IntPtr.Zero)
Face.Detect.Close(_FaceDetectEnginer);
//if (_FaceAgeEngine != IntPtr.Zero)
// Face.Age.Close(_FaceAgeEngine);
//if (_FaceGenderEngine != IntPtr.Zero)
// Face.Gender.Close(_FaceGenderEngine);
}
}
private void MatchFrame()
{
#region 获取图片 1毫秒
var bitmap = this.VideoPlayer.GetCurrentVideoFrame();
#endregion
Stopwatch sw = new Stopwatch();
sw.Start();
#region 图片转换 0.7-2微妙
var bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
var imageData = new Face.ImageData
{
u32PixelArrayFormat = 513,//Rgb24,
i32Width = bitmap.Width,
i32Height = bitmap.Height,
pi32Pitch = new int[4],
ppu8Plane = new IntPtr[4]
};
imageData.pi32Pitch[0] = bmpData.Stride;
imageData.ppu8Plane[0] = bmpData.Scan0;
sw.Stop();
_FaceResult.Score = sw.ElapsedTicks;
#endregion
try
{
#region 人脸检测 5-8毫秒
var ret = (Face.ErrorCode)Face.Detect.Detection(_FaceDetectEnginer, ref imageData, out var pDetectResult);
if (ret != Face.ErrorCode.Ok)
return;
var detectResult = Marshal.PtrToStructure<Face.DetectResult>(pDetectResult);
if (detectResult.nFace == 0)
return;
var faceRect = Marshal.PtrToStructure<Face.FaceRect>(detectResult.rcFace);
_FaceResult.Rectangle = new Rectangle((int)(faceRect.left * _RateW), (int)(faceRect.top * _RateH), (int)((faceRect.right - faceRect.left) * _RateW), (int)((faceRect.bottom - faceRect.top) * _RateH));
var faceOrient = Marshal.PtrToStructure<int>(detectResult.lfaceOrient);
#endregion
#region 性别识别基本准确 年龄识别误差太大,没什么应用场景
//Face.ExtraFaceInput faceInput = new Face.ExtraFaceInput()
//{
// lFaceNumber = facesDetect.nFace,
// pFaceRectArray = Marshal.AllocHGlobal(Marshal.SizeOf(faceRect)),
// pFaceOrientArray = Marshal.AllocHGlobal(Marshal.SizeOf(faceOrient))
//};
//Marshal.StructureToPtr(faceRect, faceInput.pFaceRectArray, false);
//Marshal.StructureToPtr(faceOrient, faceInput.pFaceOrientArray, false);
//var ageResult = Face.Age.ASAE_FSDK_AgeEstimation_Preview(_FaceAgeEngine, ref imageData, ref faceInput, out var pAgeRes);
//var ages = pAgeRes.pResult.ToStructArray<int>(pAgeRes.lFaceNumber);
//var genderResult = Face.Gender.ASGE_FSDK_GenderEstimation_Preview(_FaceGenderEngine, ref imageData, ref faceInput, out var pGenderRes);
//var genders = pGenderRes.pResult.ToStructArray<int>(pGenderRes.lFaceNumber);
//_FaceResult.Age = ages[0];
//_FaceResult.Gender = genders[0];
//Marshal.FreeHGlobal(faceInput.pFaceOrientArray);
//Marshal.FreeHGlobal(faceInput.pFaceRectArray);
#endregion
#region 获取人脸特征 160-180毫秒
var faceFeatureInput = new Face.FaceFeatureInput
{
rcFace = faceRect,
lOrient = faceOrient
};
ret = (Face.ErrorCode)Face.Match.ExtractFeature(_FaceMatchEngine, ref imageData, ref faceFeatureInput, out var faceModel);
#endregion
if (ret == Face.ErrorCode.Ok)
{
if (_RegisterClicked)
{
_RegisterFeatureData = new byte[faceModel.lFeatureSize];
Marshal.Copy(faceModel.pbFeature, _RegisterFeatureData, 0, faceModel.lFeatureSize);
}
#region 人脸识别(100张人脸) 17-20毫秒
foreach (var item in _FaceLib.Items.OrderByDescending(ii => ii.OrderId))
{
var fm = item.FaceModel;
Face.Match.FacePairMatch(_FaceMatchEngine, ref fm, ref faceModel, out float score);
if (score > 0.5)
{
item.OrderId = DateTime.Now.Ticks;
_FaceResult.ID = item.ID;
break;
}
}
#endregion
}
}
finally
{
bitmap.UnlockBits(bmpData);
if (_RegisterClicked)
{
this.pictureBox1.Invoke(new Action(() =>
{
this.pictureBox1.Image = bitmap;
}));
_RegisterClicked = false;
}
else
{
bitmap.Dispose();
}
}
}
private void VideoPlayer_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(Pens.White, _FaceResult.Rectangle);
e.Graphics.DrawString(_FaceResult.ID , this.Font, Brushes.White, _FaceResult.Rectangle.Left, _FaceResult.Rectangle.Top - 20);
}
private void VideoPlayer_Click(object sender, EventArgs e)
{
_RegisterFeatureData = null;
_RegisterClicked = true;
this.TextBoxID.Text = _FaceResult.ID;
}
private void ButtonRegister_Click(object sender, EventArgs e)
{
if (_RegisterFeatureData == null)
{
MessageBox.Show("没有人脸数据,请面对摄像头并点击视频");
return;
}
if (string.IsNullOrEmpty(this.TextBoxID.Text))
{
MessageBox.Show("请输入Id");
this.TextBoxID.Focus();
return;
}
var fileName = FeaturePath + "\\" + this.TextBoxID.Text + ".dat";
if (System.IO.File.Exists(fileName))
{
if (MessageBox.Show($"您要替换[{this.TextBoxID.Text}]的人脸数据吗?", "咨询", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.No)
return;
}
System.IO.File.WriteAllBytes(fileName, _RegisterFeatureData);
var faceModel = new Face.FaceModel
{
lFeatureSize = _RegisterFeatureData.Length,
pbFeature = Marshal.AllocHGlobal(_RegisterFeatureData.Length)
};
Marshal.Copy(_RegisterFeatureData, 0, faceModel.pbFeature, _RegisterFeatureData.Length);
_FaceLib.Items.Add(new Face.FaceLib.Item() { OrderId = DateTime.Now.Ticks, ID = this.TextBoxID.Text, FaceModel = faceModel });
}
}
}
三、运行
按F5运行,能给最大的人脸画框,如比对通过显示框上面显示ID
1.点击 视频;
2.输入 ID
3.点击 注册
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式