Skip to content

Instantly share code, notes, and snippets.

@elbruno
Created February 15, 2022 17:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elbruno/eaaf239c78fab7cb01ffd172d3ab1ed7 to your computer and use it in GitHub Desktop.
Save elbruno/eaaf239c78fab7cb01ffd172d3ab1ed7 to your computer and use it in GitHub Desktop.
opencvdetectandblurfaceusingdnn.cs
// 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 Bruno - Face 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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment