想做一个人脸识别的软件,首先得调用电脑的摄像头,在网上搜索了一番,最多的示例都是使用AForge这个库,大多是WinForm的,WPF的也有,但不够精简,整理了一下,首先Nuget如下类库:
准备工作:
1. 引用System.Windows.Forms / WindowsFormsIntegration / System.Drawing
2. Xaml界面添加代码
xmlns:wfi ="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration" xmlns:aforge ="clr-namespace:AForge.Controls;assembly=AForge.Controls"
3.XAML布局
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="55"/>
<RowDefinition Height="*"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Label Content="摄像头:" VerticalContentAlignment="Center" Margin="10"/>
<ComboBox Margin="0 10" Width="160" Name="cboCamera" SelectionChanged="CboCamera_SelectionChanged" VerticalContentAlignment="Center"/>
<Label Content="像素:" VerticalContentAlignment="Center" Margin="10"/>
<ComboBox Margin="0 10" Width="160" Name="cboPixel" VerticalContentAlignment="Center" />
<Button Margin="10" Content="连接" Width="80" Name="btnConnect" Click="BtnConnect_Click"/>
<Button Margin="0 10" Content="断开" Width="80" Name="btnBreakOff" Click="BtnBreakOff_Click"/>
<Button Margin="10" Content="拍照" Width="80" Name="btnPhotoGraph" Click="BtnPhotoGraph_Click"/>
</StackPanel>
<wfi:WindowsFormsHost Grid.Row="1">
<aforge:VideoSourcePlayer x:Name="vispShoot" />
</wfi:WindowsFormsHost>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="2">
<wfi:WindowsFormsHost Height="100" Width="200">
<aforge:PictureBox x:Name="picbPreview" BackgroundImageLayout="Zoom" />
</wfi:WindowsFormsHost>
</StackPanel>
</Grid>
4.后台CS代码
private FilterInfoCollection videoDevices;//所有摄像设备
private VideoCaptureDevice videoDevice;//摄像设备
private VideoCapabilities[] videoCapabilities;//摄像头分辨率
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);//得到机器所有接入的摄像设备
if (videoDevices.Count != 0)
{
foreach (FilterInfo device in videoDevices)
{
cboCamera.Items.Add(device.Name);//把摄像设备添加到摄像列表中
}
}
else
{
cboCamera.Items.Add("没有找到摄像头");
}
cboCamera.SelectedIndex = 0;//默认选择第一个
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
DisConnect();//关闭并释放
}
//连接按钮
private void BtnConnect_Click(object sender, RoutedEventArgs e)
{
if (videoDevice != null)//如果摄像头不为空
{
if ((videoCapabilities != null) && (videoCapabilities.Length != 0))
{
videoDevice.VideoResolution = videoCapabilities[cboPixel.SelectedIndex];//摄像头分辨率
vispShoot.VideoSource = videoDevice;//把摄像头赋给控件
vispShoot.Start();//开启摄像头
EnableControlStatus(false);
}
}
}
//断开按钮
private void BtnBreakOff_Click(object sender, RoutedEventArgs e)
{
DisConnect();//断开连接
EnableControlStatus(true);
}
//拍照按钮
private void BtnPhotoGraph_Click(object sender, RoutedEventArgs e)
{
Bitmap img = vispShoot.GetCurrentVideoFrame();//拍照
//picbPreview.Image = img;
picbPreview.BackgroundImage = img;
//这里可以根据情况,把照片存到某个路径下
//img.Save("");
}
//选择摄像头改变事件
private void CboCamera_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (videoDevices.Count != 0)
{
//获取摄像头
videoDevice = new VideoCaptureDevice(videoDevices[cboCamera.SelectedIndex].MonikerString);
GetDeviceResolution(videoDevice);//获得摄像头的分辨率
}
}
//获得摄像头的分辨率
private void GetDeviceResolution(VideoCaptureDevice videoCaptureDevice)
{
cboPixel.Items.Clear();//清空列表
videoCapabilities = videoCaptureDevice.VideoCapabilities;//设备的摄像头分辨率数组
foreach (VideoCapabilities capabilty in videoCapabilities)
{
//把这个设备的所有分辨率添加到列表
cboPixel.Items.Add($"{capabilty.FrameSize.Width} x {capabilty.FrameSize.Height}");
}
cboPixel.SelectedIndex = cboPixel.Items.Count - 1;//默认选择最后一个(分辨率最大)
}
//控件的显示切换
private void EnableControlStatus(bool status)
{
cboCamera.IsEnabled = status;
cboPixel.IsEnabled = status;
btnConnect.IsEnabled = status;
btnBreakOff.IsEnabled = !status;
btnPhotoGraph.IsEnabled = !status;
}
//关闭并释放
private void DisConnect()
{
if (vispShoot.VideoSource != null)
{
vispShoot.SignalToStop();
vispShoot.WaitForStop();
vispShoot.VideoSource = null;
}
}
效果图: