1、采取的技术
本程序的最终实现形式为Windows桌面程序,本程序主要采用微软的Winform模式进行开发,编程语言为C#。开发所使用的IDE为Visual Studio,辅助工具为Postman、son格式转换工具、Base64编码工具等。
除此之外,本程序还用到了异步技术、Base64编码技术、Json相关技术、Http传输技术等。其中,异步技术用于实时监测摄像头中出现的图像,Base64编码技术用于对图像进行编码、Json相关技术用于对数据进行统一格式处理、Http传输相关技术用于本程序与百度云服务进行通信。
2、前置条件
2.1、百度接口配置
人脸识别小程序的内部算法实现需借助百度接口,所以在启动小程序之前需要提前进行百度接口的相关配置工作。
- 打开百度智能云网址:百度智能云-云智一体深入产业,注册登录,进入如下界面。
- 点击立即使用
- 点击创建应用得到API key
2.2人脸识别程序配置
2.3下载Nuget包
AForge包用于对视频输入设备的调用和处理。
Baidu.AI包用于调用百度ai。
3、代码实现
3.1设计页面
3.2实现核心功能
(1)文件类型转换
该方法用于将 Image
对象转换为 Base64 字符串,以便后续上传或处理。
public string ConvertImageToBase64(Image file) { using (MemoryStream memoryStream = new MemoryStream()) { file.Save(memoryStream, file.RawFormat); byte[] imageBytes = memoryStream.ToArray(); return Convert.ToBase64String(imageBytes); } }
首先创建了一个
MemoryStream
对象,用于临时存储图像数据。调用
file.Save(memoryStream, file.RawFormat)
将图像数据写入到内存流中。这里使用的是图像的原始格式,而不是固定的格式(如 JPEG 或 PNG)。然后从内存流中获取字节数组
imageBytes = memoryStream.ToArray()
。最后使用
Convert.ToBase64String(imageBytes)
将字节数组转换为 Base64 编码的字符串。
将 BitmapSource
对象转换为字节数组的方法:
public byte[] BitmapSource2Byte(BitmapSource source) { try { JpegBitmapEncoder encoder = new JpegBitmapEncoder(); encoder.QualityLevel = 100; using (MemoryStream stream = new MemoryStream()) { encoder.Frames.Add(BitmapFrame.Create(source)); encoder.Save(stream); byte[] bit = stream.ToArray(); stream.Close(); return bit; } } catch (Exception ex) { ClassLoger.Error("BitmapSource2Byte", ex); } return null; }
首先创建了一个
JpegBitmapEncoder
对象,并将其质量级别设置为 100,表示最高质量。然后使用
MemoryStream
创建了一个内存流对象。将
BitmapFrame
对象添加到JpegBitmapEncoder
的Frames
集合中,BitmapFrame.Create(source)
用于从输入的BitmapSource
创建一个BitmapFrame
对象。调用
encoder.Save(stream)
将BitmapFrame
对象编码成 JPEG 格式,并写入到内存流中。最后,将内存流转换为字节数组并返回。
如果在处理过程中出现任何异常,都会被捕获,并通过
ClassLoger.Error()
方法记录错误信息。
(2)搜寻可用摄像头设备
该方法用于获取并显示电脑上已安装的视频设备。
private void button6_Click(object sender, EventArgs e) { videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); if (videoDevices != null && videoDevices.Count > 0) { foreach (FilterInfo device in videoDevices) { comboBox1.Items.Add(device.Name); } comboBox1.SelectedIndex = 0; } }
首先创建了一个
FilterInfoCollection
对象videoDevices
,并将其初始化为FilterCategory.VideoInputDevice
类型的视频输入设备集合。检查
videoDevices
是否为空,以及是否有至少一个设备可用。如果有可用的视频输入设备,则遍历
videoDevices
集合,并将每个设备的名称添加到comboBox1
中。最后,将
comboBox1
的SelectedIndex
设置为 0,即选中第一个设备。
(3)开启摄像头
该方法用于连接并启动所选的视频设备。
private void CameraConn() { if (comboBox1.Items.Count <= 0) { MessageBox.Show("请插入视频设备"); return; } videoSource = new VideoCaptureDevice(videoDevices[comboBox1.SelectedIndex].MonikerString); videoSource.DesiredFrameSize = new System.Drawing.Size(320, 240); videoSource.DesiredFrameRate = 1; videoSourcePlayer1.VideoSource = videoSource; videoSourcePlayer1.Start(); }
首先检查
comboBox1
中是否有可用的视频设备选项。如果列表为空,则弹出一个消息框提示用户插入视频设备。如果有可用的视频设备,就根据用户在
comboBox1
中选择的设备创建一个VideoCaptureDevice
对象videoSource
。这个对象代表了所选择的视频输入设备。为
videoSource
设置所需的帧大小和帧率。在这个例子中,帧大小设置为 320x240 像素,帧率设置为 1 帧/秒。将
videoSource
对象设置为videoSourcePlayer1
控件的视频源。videoSourcePlayer1
是一个用于显示视频画面的控件。最后调用
videoSourcePlayer1.Start()
方法,开始从视频设备捕获并显示视频画面。
(4)摄像头拍照
该方法用于从摄像头捕获当前帧,并将其保存为图片文件
private void button5_Click(object sender, EventArgs e) { if (comboBox1.Items.Count <= 0) { MessageBox.Show("请插入视频设备"); return; } try { if (videoSourcePlayer1.IsRunning) { BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( videoSourcePlayer1.GetCurrentVideoFrame().GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); PngBitmapEncoder pE = new PngBitmapEncoder(); pE.Frames.Add(BitmapFrame.Create(bitmapSource)); string picName = GetImagePath() + "\\" + DateTime.Now.ToFileTime() + ".jpg"; if (File.Exists(picName)) { File.Delete(picName); } using (Stream stream = File.Create(picName)) { pE.Save(stream); } if (videoSourcePlayer1 != null && videoSourcePlayer1.IsRunning) { videoSourcePlayer1.SignalToStop(); videoSourcePlayer1.WaitForStop(); } this.Close(); } } catch (Exception ex) { MessageBox.Show("摄像头异常:" + ex.Message); } }
首先检查
comboBox1
中是否有可用的视频设备选项。如果没有,则弹出一个消息框提示用户插入视频设备。如果有可用的视频设备,则尝试执行以下操作:
- 检查
videoSourcePlayer1
控件是否正在运行。 - 从
videoSourcePlayer1
获取当前的视频帧,并将其转换为BitmapSource
对象。 - 创建一个
PngBitmapEncoder
对象,并将BitmapSource
添加到其帧集合中。 - 生成一个以当前时间戳命名的 JPEG 文件路径。
- 如果该文件已经存在,则先删除它。
- 使用
File.Create
创建文件,并使用pE.Save(stream)
将编码后的图像数据写入文件。 - 最后,停止
videoSourcePlayer1
的视频播放,并关闭当前窗口。
- 检查
如果在执行上述操作时发生任何异常,则会捕获并显示一个消息框,内容为"摄像头异常:"后跟异常消息。
4、效果展示
4.1、人脸对比
选择两张图片路径后,点击图片识别按钮,可得到匹配相似度。例如,识别结果为85%。
4.2人脸登录
使用摄像头获取当前帧,然后与百度AI库中的所有人脸进行比对,如果相似度高于某个阈值则返回该人脸的用户名,并提示登录成功。
4.3、人脸识别
选择图片路径后,点击人脸识别按钮会返回人脸识别信息,展示具体的人脸特征和匹配度。
5、总结
通过上述代码和步骤,可以轻松实现从摄像头捕捉视频帧并进行人脸识别的功能。利用视频捕捉技术与百度AI的人脸识别能力相结合,我们可以开发出各种智能化的应用程序,提高系统的智能水平,为用户带来更加安全、便捷的体验。期待大家在CSDN上分享更多这方面的技术实践和创新成果!