WPF 实现人脸检测
WPF開發者QQ群
此群已滿340500857?,請加新群458041663
?? ??? 由于微信群人數太多入群請添加小編微信號
?yanjinhuawechat 或 W_Feng_aiQ?邀請入群
?需備注WPF開發者?
? PS:有更好的方式歡迎推薦。
??接著上一篇
? 利用已經訓練好的數據文件,檢測人臉 地址如下:
? https://github.com/opencv/opencv/tree/master/data/haarcascades
使用NuGet如下:
01
—
代碼如下
一、創建MainWindow.xaml代碼如下。
<ws:Window?x:Class="OpenCVSharpExample.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:ws="https://github.com/WPFDevelopersOrg.WPFDevelopers.Minimal"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:OpenCVSharpExample"Icon="OpenCV_Logo.png"mc:Ignorable="d"?WindowStartupLocation="CenterScreen"Title="OpenCVSharpExample?https://github.com/WPFDevelopersOrg"?Height="450"?Width="800"><Grid?Margin="4"><Grid.ColumnDefinitions><ColumnDefinition?MinWidth="500"?Width="8*"/><ColumnDefinition?Width="2*"?MinWidth="200"/></Grid.ColumnDefinitions><Image?Grid.Row="0"?Name="imgViewport"/><GridSplitter?Grid.Column="0"?HorizontalAlignment="Right"?Width="2"/><GroupBox?Header="Operation"?Grid.Column="1"?Margin="0,0,4,0"><Grid><Grid.RowDefinitions><RowDefinition/><RowDefinition/><RowDefinition?Height="Auto"/></Grid.RowDefinitions><StackPanel?Grid.Row="0"?HorizontalAlignment="Left"><CheckBox?IsChecked="{Binding?IsSave,RelativeSource={RelativeSource?AncestorType=local:MainWindow}}"VerticalAlignment="Center"?Content="Save"?Margin="0,4"/><CheckBox?IsChecked="{Binding?IsFace,RelativeSource={RelativeSource?AncestorType=local:MainWindow}}"VerticalAlignment="Center"?Content="Face"?Margin="0,4"/><ComboBox?Name="ComboBoxCamera"?ItemsSource="{Binding?CameraArray,RelativeSource={RelativeSource?AncestorType=local:MainWindow}}"?SelectedIndex="{Binding?CameraIndex,RelativeSource={RelativeSource?AncestorType=local:MainWindow}}"SelectionChanged="ComboBoxCamera_SelectionChanged"/></StackPanel><StackPanel?Orientation="Horizontal"?Grid.Row="2"?HorizontalAlignment="Center"><Button?Name="btPlay"?Content="Play"?Style="{StaticResource?PrimaryButton}"?Click="btPlay_Click"?IsEnabled="False"/><Button?Name="btStop"?Click="btStop_Click"?Content="Stop"?Margin="4,0"/></StackPanel></Grid></GroupBox></Grid> </ws:Window>二、MainWindow.xaml.cs代碼如下。
using?OpenCvSharp; using?OpenCvSharp.Extensions; using?System; using?System.Collections.Generic; using?System.ComponentModel; using?System.Drawing; using?System.Drawing.Imaging; using?System.Globalization; using?System.IO; using?System.Management; using?System.Threading; using?System.Windows; using?System.Windows.Controls; using?System.Windows.Media.Imaging; using?System.Windows.Threading;namespace?OpenCVSharpExample {///?<summary>///?MainWindow.xaml?的交互邏輯///?</summary>public?partial?class?MainWindow{private?VideoCapture?capCamera;private?VideoWriter?videoWriter;private?Mat?matImage?=?new?Mat();private?Thread?cameraThread;private?Thread?writerThread;private?CascadeClassifier?haarCascade;private?WriteableBitmap?writeableBitmap;private?Rectangle?rectangle;private?Mat?gray;private?Mat?result;private?OpenCvSharp.Rect[]?faces;public?List<string>?CameraArray{get?{?return?(List<string>)GetValue(CameraArrayProperty);?}set?{?SetValue(CameraArrayProperty,?value);?}}public?static?readonly?DependencyProperty?CameraArrayProperty?=DependencyProperty.Register("CameraArray",?typeof(List<string>),?typeof(MainWindow),?new?PropertyMetadata(null));public?int?CameraIndex{get?{?return?(int)GetValue(CameraIndexProperty);?}set?{?SetValue(CameraIndexProperty,?value);?}}public?static?readonly?DependencyProperty?CameraIndexProperty?=DependencyProperty.Register("CameraIndex",?typeof(int),?typeof(MainWindow),?new?PropertyMetadata(0));public?bool?IsSave{get?{?return?(bool)GetValue(IsSaveProperty);?}set?{?SetValue(IsSaveProperty,?value);?}}public?static?readonly?DependencyProperty?IsSaveProperty?=DependencyProperty.Register("IsSave",?typeof(bool),?typeof(MainWindow),?new?UIPropertyMetadata(IsSaveChanged));private?static?void?IsSaveChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e){var?mainWindow?=?d?as?MainWindow;if?(e.NewValue?!=?null){var?save?=?(bool)?e.NewValue;if?(save)mainWindow.StartRecording();elsemainWindow.StopRecording();}}public?bool?IsFace{get?{?return?(bool)GetValue(IsFaceProperty);?}set?{?SetValue(IsFaceProperty,?value);?}}public?static?readonly?DependencyProperty?IsFaceProperty?=DependencyProperty.Register("IsFace",?typeof(bool),?typeof(MainWindow),?new?UIPropertyMetadata(IsFaceChanged));private?static?void?IsFaceChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e){var?mainWindow?=?d?as?MainWindow;if?(e.NewValue?!=?null){var?save?=?(bool)e.NewValue;if?(save)mainWindow.CreateFace();elsemainWindow.CloseFace();}}public?MainWindow(){InitializeComponent();Width?=?SystemParameters.WorkArea.Width?/?1.5;Height?=?SystemParameters.WorkArea.Height?/?1.5;this.Loaded?+=?MainWindow_Loaded;}private?void?MainWindow_Loaded(object?sender,?RoutedEventArgs?e){InitializeCamera();}private?void?ComboBoxCamera_SelectionChanged(object?sender,?SelectionChangedEventArgs?e){if?(CameraArray.Count?-?1?<?CameraIndex)return;if?(capCamera?!=?null?&&?cameraThread?!=?null){cameraThread.Abort();StopDispose();}CreateCamera();writeableBitmap?=?new?WriteableBitmap(capCamera.FrameWidth,?capCamera.FrameHeight,?0,?0,?System.Windows.Media.PixelFormats.Bgra32,?null);imgViewport.Source?=?writeableBitmap;}private?void?btStop_Click(object?sender,?RoutedEventArgs?e){StopDispose();btStop.IsEnabled?=?false;}protected?override?void?OnClosing(CancelEventArgs?e){if(WPFDevelopers.Minimal.Controls.MessageBox.Show("是否關閉系統?",?"詢問",?MessageBoxButton.OKCancel,?MessageBoxImage.Question)?!=?MessageBoxResult.OK)?{e.Cancel?=?true;return;}}protected?override?void?OnClosed(EventArgs?e){StopDispose();}private?void?btPlay_Click(object?sender,?RoutedEventArgs?e){btPlay.IsEnabled?=?false;btStop.IsEnabled?=?true;CreateCamera();}#region?方法void?CloseFace(){if?(haarCascade?!=?null){haarCascade.Dispose();haarCascade?=?null;gray.Dispose();gray?=?null;result.Dispose();result?=?null;faces?=?null;}}void?CreateFace(){var?facePath?=?System.IO.Path.Combine(System.Environment.CurrentDirectory,?"Data/haarcascade_frontalface_default.xml");if?(!System.IO.File.Exists(facePath)){WPFDevelopers.Minimal.Controls.MessageBox.Show("缺少人臉檢測文件。",?"錯誤",?MessageBoxButton.OK,?MessageBoxImage.Error);return;}haarCascade?=?new?CascadeClassifier(facePath);}private?void?InitializeCamera(){CameraArray?=?GetAllConnectedCameras();}List<string>?GetAllConnectedCameras(){var?cameraNames?=?new?List<string>();using?(var?searcher?=?new?ManagementObjectSearcher("SELECT?*?FROM?Win32_PnPEntity?WHERE?(PNPClass?=?'Image'?OR?PNPClass?=?'Camera')")){foreach?(var?device?in?searcher.Get()){cameraNames.Add(device["Caption"].ToString());}}return?cameraNames;}void?CreateCamera(){capCamera?=?new?VideoCapture(CameraIndex);capCamera.Fps?=?30;cameraThread?=?new?Thread(PlayCamera);cameraThread.Start();}private?void?PlayCamera(){while?(capCamera?!=?null?&&?!capCamera.IsDisposed){capCamera.Read(matImage);if?(matImage.Empty())?break;Dispatcher.Invoke(new?Action(()?=>{if?(IsFace){result?=?matImage.Clone();gray?=?new?Mat();Cv2.CvtColor(result,?gray,?ColorConversionCodes.BGR2GRAY);faces?=?haarCascade.DetectMultiScale(gray,?1.3);if?(faces.Length?>?0){Cv2.Rectangle(matImage,?faces[0],?Scalar.Green,?2);}result.Dispose();}}));using?(var?img?=?BitmapConverter.ToBitmap(matImage)){var?now?=?DateTime.Now;var?g?=?Graphics.FromImage(img);var?brush?=?new?SolidBrush(System.Drawing.Color.Red);System.Globalization.CultureInfo?cultureInfo?=?new?CultureInfo("zh-CN");var?week?=?cultureInfo.DateTimeFormat.GetAbbreviatedDayName(now.DayOfWeek);g.DrawString($"{week}?{?now.ToString("yyyy年MM月dd日?HH:mm:ss?")}?",?new?System.Drawing.Font(System.Drawing.SystemFonts.DefaultFont.Name,?System.Drawing.SystemFonts.DefaultFont.Size),?brush,?new?PointF(0,?matImage.Rows?-?20));brush.Dispose();g.Dispose();rectangle?=?new?Rectangle(0,?0,?img.Width,?img.Height);Dispatcher.Invoke(new?Action(()?=>{WriteableBitmapHelper.BitmapCopyToWriteableBitmap(img,?writeableBitmap,?rectangle,?0,?0,?System.Drawing.Imaging.PixelFormat.Format32bppArgb);}));img.Dispose();};Thread.Sleep(100);}}private?void?StartRecording(){if?(capCamera?==?null){WPFDevelopers.Minimal.Controls.MessageBox.Show("未開啟攝像機",?"提示",?MessageBoxButton.OKCancel,?MessageBoxImage.Error);return;}var?videoFile?=?System.IO.Path.Combine(System.Environment.CurrentDirectory,?"Video");if?(!System.IO.Directory.Exists(videoFile))System.IO.Directory.CreateDirectory(videoFile);var?currentTime?=?System.IO.Path.Combine(videoFile,?$"{DateTime.Now.ToString("yyyyMMddHHmmsshh")}.avi");videoWriter?=?new?VideoWriter(currentTime,?FourCCValues.XVID,?capCamera.Fps,?new?OpenCvSharp.Size(capCamera.FrameWidth,?capCamera.FrameHeight));writerThread?=?new?Thread(AddCameraFrameToRecording);writerThread.Start();}private?void?StopRecording(){if?(videoWriter?!=?null?&&?!videoWriter.IsDisposed){videoWriter.Release();videoWriter.Dispose();videoWriter?=?null;}}private?void?AddCameraFrameToRecording(){var?waitTimeBetweenFrames?=?1_000?/?capCamera.Fps;var?lastWrite?=?DateTime.Now;while?(!videoWriter.IsDisposed){if?(DateTime.Now.Subtract(lastWrite).TotalMilliseconds?<?waitTimeBetweenFrames)continue;lastWrite?=?DateTime.Now;videoWriter.Write(matImage);}}void?StopDispose(){if?(capCamera?!=?null?&&?capCamera.IsOpened()){capCamera.Dispose();capCamera?=?null;}if?(videoWriter?!=?null?&&?!videoWriter.IsDisposed){videoWriter.Release();videoWriter.Dispose();videoWriter?=?null;}CloseFace();btPlay.IsEnabled?=?true;GC.Collect();}void?CreateRecord(){cameraThread?=?new?Thread(PlayCamera);cameraThread.Start();}#endregion} }02
—
效果預覽
鳴謝素材提供者 -?OpenCVSharp
源碼地址如下
Github:https://github.com/WPFDevelopersOrg
https://github.com/WPFDevelopersOrg/OpenCVSharpExample
Gitee:https://gitee.com/WPFDevelopersOrg
WPF開發者QQ群:?340500857?
Github:https://github.com/WPFDevelopersOrg
出處:https://www.cnblogs.com/yanjinhua
版權:本作品采用「署名-非商業性使用-相同方式共享 4.0 國際」許可協議進行許可。
轉載請著名作者 出處 https://github.com/WPFDevelopersOrg
掃一掃關注我們,
更多知識早知道!
點擊閱讀原文可跳轉至源代碼
總結
以上是生活随笔為你收集整理的WPF 实现人脸检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一篇文章了解Liquid模版引擎
- 下一篇: 2021 .NET Conf China