Детекция лиц с Web-камеры
В этом туториале вы узнаете, как детектировать лица на видеопотоке с Web-камеры, используя объект Capturer из Face SDK API. Задетектированные лица выделяются зеленым ограничивающим прямоугольником.
Кроме Face SDK и Visual Studio 2019 вам потребуется камера, подключенная к Вашему ПК (например, вебкамера). Проект можно собрать и запустить на Windows.
Вы можете найти исходники проекта в Face SDK examples/tutorials/csharp/FirstApp
Подготовка проекта
Запустите Visual Studio и создайте новый проект New > Project > Windows Forms application (.NET FrameWork) > Next. После этого Вы можете указать имя и расположение Вашего проекта. Вы увидите Form Designer, в котором вы можете начать построение приложения Windows Forms.
Кликните на форме два раза левой кнопкой мыши. Это создаст новый метод
Form1_Load
вForm1.cs
. Это пригодится в дальнейшем.Откройте Build > Configuration Manager. В поле
Platform
, в выпадающем списке, выберите<New...>
, затем выберите платформуx64
.Нажмите
OK > Close
.Откройте Form Designer и добавьте компонент PictureBox на форму (находится в View > Toolbox > All Windows Forms). Для созданного
pictureBox1
выберите Size ModeZoom
и кликнитеDock in parent container
.
Получения кадров с вебкамеры
Для работы с вебкамерой мы будем использовать библиотеки Emgu.CV, Emgu.CV.Bitmap, Emgu.CV.runtime.windows. Для установки пакетов используйте
NuGet Package Manager
Tools > NuGet Package Manager > Manage Nuget Packages for Solution. Выберите вкладкуBrowse
, найдите пакеты и установите их.Откройте в редакторе
Form1.cs
и добавьте импорты в начало кода:using Emgu.CV;
using Emgu.CV.Structure;Добавьте метод
GetFrame
в класс, изменитеForm1_Load
. Также добавьте переменныеcamera
иcamera_id
с номером устройства.namespace FirstApp
{
public partial class Form1 : Form
{
private int camera_id = 0;
private VideoCapture camera;
...
private void GetFrame(object sender, EventArgs e)
{
Image<Bgr, byte> image = camera.QueryFrame().ToImage<Bgr, byte>();
pictureBox1.Image = image.ToBitmap();
}
private void Form1_Load(object sender, EventArgs e)
{
camera = new VideoCapture(camera_id);
if (camera.IsOpened)
{
Application.Idle += GetFrame;
}else
{
MessageBox.Show("Camera not opened!", "Camera error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
}
}
...
}
}Теперь Вы можете собрать и запустить программу Build > Run Code Analysis on Solution. Убедитесь, что видео с камеры отображается.
Подключение FaceSDK к проекту
Откройте View > Solution Explorer > References (правый клик мыши) > Add Reference -> Browse и добавьте
FacerecCSharpWrapper.dll
из папки<facesdk_root_dir>\bin
. НажимитеOK
.Для автоматического копирования библиотек в Ваш проект откройте Project > {PROJECT_NAME} Properties... > Build Events > Edit Pre-build... и добавьте строки:
set facesdk_root_dir=<facesdk_root_dir>
xcopy /Y "%facesdk_root_dir%\bin\facerec.dll" "$(TargetDir)"
xcopy /Y "%facesdk_root_dir%\bin\sense4.dll" "$(TargetDir)"
xcopy /Y "%facesdk_root_dir%\bin\tensorflow.dll" "$(TargetDir)"Примечание: замените
<facesdk_root_dir>
на путь, где установлен FaceSDK.Нажмите
OK
.В
Form1.cs
добавьте импорты в начало кода:using System.Runtime.InteropServices;
using VDT.FaceRecognition.SDK;Добавьте приватные переменные в класс
Form1
:private String faceSDKRootDir = "<facesdk_root_dir>";
private Capturer capturer;Примечание: замените
<facesdk_root_dir>
на путь, где установлен FaceSDK.Перед строкой
Application.Idle ...
добавьте создание сервиса FaceSDK и объекта capturer в методForm1_Load
:private void Form1_Load_1(object sender, EventArgs e)
{
...
if (camera.IsOpened)
{
FacerecService service = FacerecService.createService(faceSDKRootDir + "\\conf\\facerec", "");
FacerecService.Config capturerConfig = new FacerecService.Config("fda_tracker_capturer_uld.xml");
capturer = service.createCapturer(capturerConfig);
Application.Idle += GetFrame;
}
else
...
}Последним шагом нужно добавить метод
drawDetections
, который будет детектировать лица на изображении и отрисовывать ограничивающие прямоугольники вокруг лица.private void GetFrame(object sender, EventArgs e)
{
Image<Bgr, byte> image = camera.QueryFrame().ToImage<Bgr, byte>();
drawDetections(image);
pictureBox1.Image = image.ToBitmap();
}
private void drawDetections(Image<Bgr, byte> image)
{
Mat frame_m = image.Mat.Clone();
byte[] data = new byte[frame_m.Total.ToInt32() * frame_m.NumberOfChannels];
Marshal.Copy(frame_m.DataPointer, data, 0, (int)data.Length);
RawImage ri_frame = new RawImage(frame_m.Width, frame_m.Height, RawImage.Format.FORMAT_BGR, data);
List<RawSample> detected = capturer.capture(ri_frame);
foreach (RawSample sample in detected)
{
RawSample.Rectangle rect = sample.getRectangle();
image.Draw(new Rectangle((int)rect.x,
(int)rect.y,
(int)rect.width,
(int)rect.height),
new Bgr(0, 255, 0),
2);
}
}Теперь Вы можете запустить приложение и посмотреть как это работает.