#OpenCV – Detect and blur faces 😁 using DNN in C#

Hi !

NET is in anniversary mode, so I think it will be a good idea to share some camera samples in C#. For these demos I’m using C# 6 and OpenCVSharp as OpenCV wrapper for .NET.

Today post: detect a face using a DNN model and blur the face area. This demo also show the detected face in a separated window (just for fun). And I added the Frame per second (FPS) as additional information in the main window

Easy to implement, and also easy to read:

face blur demo in csharp using dnn

Code Sample

// Copyright (c) 2022
// Author : Bruno Capuano
// Create Time : 2022 Feb
// Change Log :
// – Open a camera feed from a local USB webcam and analyze each frame to detect faces using a pretrained DNN model
// – Download model and prototxt from https://github.com/spmallick/learnopencv/tree/master/FaceDetectionComparison/models
// – When a face is detected, the app will blur the face zone in the main window
// – When a face is detected, the app will show the original detected face in a separated window
// – Press [F] to enable / disable the face detection process
// – Press [Q] to quit the app
//
// The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using OpenCvSharp;
using OpenCvSharp.Dnn;
// download model and prototxt from https://github.com/spmallick/learnopencv/tree/master/FaceDetectionComparison/models
const string configFile = "deploy.prototxt";
const string faceModel = "res10_300x300_ssd_iter_140000_fp16.caffemodel";
using var faceNet = CvDnn.ReadNetFromCaffe(configFile, faceModel);
var image = new Mat();
var detectFaces = true;
var run = true;
using var capture = new VideoCapture(0);
using var window = new Window("El BrunoFace Detector DNN");
using var windowFace = new Window("Face");
while (run)
{
var startTime = DateTime.Now;
capture.Read(image);
if (image.Empty())
break;
var newSize = new Size(640, 480);
using var frame = new Mat();
Cv2.Resize(image, frame, newSize);
if (detectFaces)
{
int frameHeight = frame.Rows;
int frameWidth = frame.Cols;
using var blob = CvDnn.BlobFromImage(frame, 1.0, new Size(300, 300),
new Scalar(104, 117, 123), false, false);
faceNet.SetInput(blob, "data");
using var detection = faceNet.Forward("detection_out");
using var detectionMat = new Mat(detection.Size(2), detection.Size(3), MatType.CV_32F,
detection.Ptr(0));
for (int i = 0; i < detectionMat.Rows; i++)
{
float confidence = detectionMat.At<float>(i, 2);
if (confidence > 0.7)
{
int x1 = (int)(detectionMat.At<float>(i, 3) * frameWidth);
int y1 = (int)(detectionMat.At<float>(i, 4) * frameHeight);
int x2 = (int)(detectionMat.At<float>(i, 5) * frameWidth);
int y2 = (int)(detectionMat.At<float>(i, 6) * frameHeight);
Cv2.Rectangle(frame, new Point(x1, y1), new Point(x2, y2), Scalar.Green);
// create a new Mat with the detected face
var faceImg = new Mat(frame,
new OpenCvSharp.Range(y1, y2),
new OpenCvSharp.Range(x1, x2));
windowFace.Image = faceImg;
// blur the face area in the original frame
var faceBlur = new Mat();
Cv2.GaussianBlur(faceImg, faceBlur, new Size(23, 23), 30);
frame[new OpenCvSharp.Range(y1, y2), new OpenCvSharp.Range(x1, x2)] = faceBlur;
}
}
}
var diff = DateTime.Now startTime;
var fpsInfo = $"FPS: Nan";
if (diff.Milliseconds > 0)
{
var fpsVal = 1.0 / diff.Milliseconds * 1000;
fpsInfo = $"FPS: {fpsVal:00}";
}
Cv2.PutText(frame, fpsInfo, new Point(10, 20), HersheyFonts.HersheyComplexSmall, 1, Scalar.White);
window.Image = frame;
switch ((char)Cv2.WaitKey(100))
{
case (char)27: // ESC
run = false;
break;
case 'f':
detectFaces = !detectFaces;
break;
}
}

Happy coding!

Greetings

El Bruno

More posts in my blog ElBruno.com.


Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: