Face Detection in a Video Frames
In this tutorial, you'll learn how to detect faces in a video frames from your camera using Capturer object from Face SDK API. Detected faces are highlighted with a green rectangle.
Besides Face SDK and Visual Studio 2019, you'll need a camera connected to your PC (for example, a webcam). You can build and run this project on Windows.
You can find the tutorial project in Face SDK: examples/tutorials/csharp/FirstApp
Prepare project
Run Visual Studio and create new project New > Project > Windows Forms application (.NET FrameWork) > Next. Then you can to mention the name and location of our project. You will see a Form Designer displayed in Visual Studio. In this Form Designer, you will start building a Windows Forms application.
Double-click the left mouse button on the form. This will create a new
Form1_Load
method in theForm1.cs
. It will be needed further.Open Build > Configuration Manager. In the field
Platform
in the combobox select<New...>
and choose platformx64
.Click
OK > Close
.Open the Form Designer and add the PictureBox component to the form (located in View > Toolbox > All Windows Forms). For the created
pictureBox1
clickDock in parent container
and select Size ModeZoom
.
Getting a video from a webcam
To work with the webcam, we will use the Emgu.CV and Emgu.CV.Bitmap libraries. To install the package use
NuGet Package Manager
(Tools > NuGet Package Manager > Manage Nuget Packages for Solution). Select theBrowse
tab, find the packages and install them.Open the
Form1.cs
code editor and add imports to the beginning of the code:using Emgu.CV;
using Emgu.CV.Structure;Add the
GetFrame
method to the class, modifyForm1_Load
. Also adds the variablescamera
andcamera_id
with device number: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();
}
}
...
}
}Now you can build and start program Build > Run Code Analysis on Solution and make sure that the video from the camera is displayed.
Adding FaceSDK to a project
Open View > Solution Explorer > References (right-click) > Add Reference -> Browse and add
FacerecCSharpWrapper.dll
from<facesdk_root_dir>\bin
folder. ClickOK
.To automatically copy libraries into your project open Project > {PROJECT_NAME} Properties... > Build Events > Edit Pre-build... and add lines:
set facesdk_root_dir=<facesdk_root_dir>
xcopy /Y "%facesdk_bin%\bin\facerec.dll" "$(TargetDir)"
xcopy /Y "%facesdk_bin%\bin\sense4.dll" "$(TargetDir)"
xcopy /Y "%facesdk_bin%\bin\tensorflow.dll" "$(TargetDir)"Note: replace
<facesdk_root_dir>
with the path where the installed FaceSDK is located.Click
OK
.In
Form1.cs
add imports:using System.Runtime.InteropServices;
using VDT.FaceRecognition.SDK;Add private variables into
Form1
class:private String faceSDKRootDir = "<facesdk_root_dir>";
private Capturer capturer;Note: replace
<facesdk_root_dir>
with the path where the installed FaceSDK is located.Before the line
Application.Idle ...
add the creation of the FaceSDK service and the capturer to theForm1_Load
method:FacerecService service = FacerecService.createService(faceSDKRootDir + "\\conf\\facerec", "");
FacerecService.Config capturerConfig = new FacerecService.Config("fda_tracker_capturer_uld.xml");
capturer = service.createCapturer(capturerConfig);The final step is to add a method that will detect the face in the image and draw a frame around the face.
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);
}
}Also add its call to the
GetFrame
method:private void GetFrame(object sender, EventArgs e)
{
Image<Bgr, byte> image = camera.QueryFrame().ToImage<Bgr, byte>();
drawDetections(image);
pictureBox1.Image = image.ToBitmap();
}Now you can launch the application and check how it works.