Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 24 additions & 9 deletions examples/Benchmark/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ internal class Program

#region Fields

private static FaceRecognition FaceRecognition;
private static FaceRecognition _FaceRecognition;

private static bool _UseCnn = false;

#endregion

Expand All @@ -31,6 +33,7 @@ private static void Main(string[] args)
app.HelpOption("-h|--help");

var modelsOption = app.Option("-m|--model", "model files directory path", CommandOptionType.SingleValue);
var cnnOption = app.Option("-c|--cnn", "use cnn", CommandOptionType.NoValue);

app.OnExecute(() =>
{
Expand All @@ -47,7 +50,9 @@ private static void Main(string[] args)
return -1;
}

FaceRecognition = FaceRecognition.Create(directory);
_UseCnn = cnnOption.HasValue();

_FaceRecognition = FaceRecognition.Create(directory);

var testImages = new[]
{
Expand Down Expand Up @@ -84,7 +89,7 @@ private static void Main(string[] args)

#region Helpers

private static Tuple<double, double> RunTest<T>(string path, Func<string, T> setup, Action<T> test, int iterationsPerTest = 5, int testsToRun = 10)
private static Tuple<double, double> RunTest<T>(string path, Func<string, T> setup, Action<T> test, int iterationsPerTest = 5, int testsToRun = 10, bool useCnn = false)
{
var image = setup(path);

Expand All @@ -111,7 +116,8 @@ private static Tuple<double, double> RunTest<T>(string path, Func<string, T> set
private static Tuple<Image, Location[]> SetupEncodeFace(string path)
{
var image = FaceRecognition.LoadImageFile(path);
var locations = FaceRecognition.FaceLocations(image).ToArray();
var model = _UseCnn ? Model.Cnn : Model.Hog;
var locations = _FaceRecognition.FaceLocations(image, model: model).ToArray();
return new Tuple<Image, Location[]>(image, locations);
}

Expand All @@ -123,7 +129,8 @@ private static Image SetupEndToEnd(string path)
private static Tuple<Image, Location[]> SetupFaceLandmarks(string path)
{
var image = FaceRecognition.LoadImageFile(path);
var locations = FaceRecognition.FaceLocations(image).ToArray();
var model = _UseCnn ? Model.Cnn : Model.Hog;
var locations = _FaceRecognition.FaceLocations(image, model: model).ToArray();
return new Tuple<Image, Location[]>(image, locations);
}

Expand All @@ -134,22 +141,30 @@ private static Image SetupLocateFaces(string path)

private static void TestEncodeFace(Tuple<Image, Location[]> tuple)
{
var encoding = FaceRecognition.FaceEncodings(tuple.Item1, tuple.Item2).First();
var model = _UseCnn ? Model.Cnn : Model.Hog;
var encoding = _FaceRecognition.FaceEncodings(tuple.Item1, tuple.Item2, model: model);
foreach (var faceEncoding in encoding)
faceEncoding.Dispose();
}

private static void TestEndToEnd(Image image)
{
var encoding = FaceRecognition.FaceEncodings(image).First();
var model = _UseCnn ? Model.Cnn : Model.Hog;
var encoding = _FaceRecognition.FaceEncodings(image, model: model);
foreach (var faceEncoding in encoding)
faceEncoding.Dispose();
}

private static void TestFaceLandmarks(Tuple<Image, Location[]> tuple)
{
var landmarks = FaceRecognition.FaceLandmark(tuple.Item1, tuple.Item2).First();
var model = _UseCnn ? Model.Cnn : Model.Hog;
var landmarks = _FaceRecognition.FaceLandmark(tuple.Item1, tuple.Item2, model: model).First();
}

private static void TestLocateFaces(Image image)
{
var faceLocations = FaceRecognition.FaceLocations(image).ToArray();
var model = _UseCnn ? Model.Cnn : Model.Hog;
var faceLocations = _FaceRecognition.FaceLocations(image, model: model).ToArray();
}

#endregion
Expand Down
1 change: 1 addition & 0 deletions examples/Benchmark/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ This program support the following argument and option.
|Argument|Description|
|:---|:---|
|-m\|--model|Directory path includes model files|
|-c\|--cnn|Use Cnn|

## 5. Other

Expand Down
40 changes: 26 additions & 14 deletions src/FaceRecognitionDotNet/FaceRecognition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -365,22 +365,27 @@ public static IEnumerable<double> FaceDistances(IEnumerable<FaceEncoding> faceEn
/// <param name="image">The image contains faces. The image can contain multiple faces.</param>
/// <param name="knownFaceLocation">The enumerable collection of location rectangle for faces. If specified null, method will find face locations.</param>
/// <param name="numJitters">The number of times to re-sample the face when calculating encoding.</param>
/// <param name="model">The model of face detector.</param>
/// <param name="predictorModel">The dimension of vector which be returned from detector.</param>
/// <param name="model">The model of face detector to detect in image. If <paramref name="knownFaceLocation"/> is not null, this value is ignored.</param>
/// <returns>An enumerable collection of face feature data corresponds to all faces in specified image.</returns>
/// <exception cref="ArgumentNullException"><paramref name="image"/> is null.</exception>
/// <exception cref="ObjectDisposedException"><paramref name="image"/> or this object or custom face landmark detector is disposed.</exception>
/// <exception cref="NotSupportedException"><see cref="PredictorModel.Custom"/> is not supported.</exception>
public IEnumerable<FaceEncoding> FaceEncodings(Image image, IEnumerable<Location> knownFaceLocation = null, int numJitters = 1, PredictorModel model = PredictorModel.Small)
public IEnumerable<FaceEncoding> FaceEncodings(Image image,
IEnumerable<Location> knownFaceLocation = null,
int numJitters = 1,
PredictorModel predictorModel = PredictorModel.Small,
Model model = Model.Hog)
{
if (image == null)
throw new ArgumentNullException(nameof(image));
if (model == PredictorModel.Custom)
if (predictorModel == PredictorModel.Custom)
throw new NotSupportedException("FaceRecognitionDotNet.PredictorModel.Custom is not supported.");

image.ThrowIfDisposed();
this.ThrowIfDisposed();

var rawLandmarks = this.RawFaceLandmarks(image, knownFaceLocation, model);
var rawLandmarks = this.RawFaceLandmarks(image, knownFaceLocation, predictorModel, model);
foreach (var landmark in rawLandmarks)
{
var ret = new FaceEncoding(FaceRecognitionModelV1.ComputeFaceDescriptor(this._FaceEncoder, image, landmark, numJitters));
Expand All @@ -394,20 +399,24 @@ public IEnumerable<FaceEncoding> FaceEncodings(Image image, IEnumerable<Location
/// </summary>
/// <param name="faceImage">The image contains faces. The image can contain multiple faces.</param>
/// <param name="faceLocations">The enumerable collection of location rectangle for faces. If specified null, method will find face locations.</param>
/// <param name="model">The model of face detector.</param>
/// <param name="predictorModel">The dimension of vector which be returned from detector.</param>
/// <param name="model">The model of face detector to detect in image. If <paramref name="faceLocations"/> is not null, this value is ignored.</param>
/// <returns>An enumerable collection of dictionary of face parts locations (eyes, nose, etc).</returns>
/// <exception cref="ArgumentNullException"><paramref name="faceImage"/> is null.</exception>
/// <exception cref="ObjectDisposedException"><paramref name="faceImage"/> or this object or custom face landmark detector is disposed.</exception>
/// <exception cref="NotSupportedException">The custom face landmark detector is not ready.</exception>
public IEnumerable<IDictionary<FacePart, IEnumerable<FacePoint>>> FaceLandmark(Image faceImage, IEnumerable<Location> faceLocations = null, PredictorModel model = PredictorModel.Large)
public IEnumerable<IDictionary<FacePart, IEnumerable<FacePoint>>> FaceLandmark(Image faceImage,
IEnumerable<Location> faceLocations = null,
PredictorModel predictorModel = PredictorModel.Large,
Model model = Model.Hog)
{
if (faceImage == null)
throw new ArgumentNullException(nameof(faceImage));

faceImage.ThrowIfDisposed();
this.ThrowIfDisposed();

if (model == PredictorModel.Custom)
if (predictorModel == PredictorModel.Custom)
{
if (this._CustomFaceLandmarkDetector == null)
throw new NotSupportedException("The custom face landmark detector is not ready.");
Expand All @@ -416,7 +425,7 @@ public IEnumerable<IDictionary<FacePart, IEnumerable<FacePoint>>> FaceLandmark(I
throw new ObjectDisposedException($"{nameof(CustomFaceLandmarkDetector)}", "The custom face landmark detector is disposed.");
}

var landmarks = this.RawFaceLandmarks(faceImage, faceLocations, model).ToArray();
var landmarks = this.RawFaceLandmarks(faceImage, faceLocations, predictorModel, model).ToArray();
var landmarkTuples = landmarks.Select(landmark => Enumerable.Range(0, (int)landmark.Parts)
.Select(index => new FacePoint(new Point(landmark.GetPart((uint)index)), index)).ToArray());

Expand All @@ -426,7 +435,7 @@ public IEnumerable<IDictionary<FacePart, IEnumerable<FacePoint>>> FaceLandmark(I
{

// For a definition of each point index, see https://cdn-images-1.medium.com/max/1600/1*AbEg31EgkbXSQehuNJBlWg.png
switch (model)
switch (predictorModel)
{
case PredictorModel.Large:
results.AddRange(landmarkTuples.Select(landmarkTuple => new Dictionary<FacePart, IEnumerable<FacePoint>>
Expand Down Expand Up @@ -465,7 +474,7 @@ public IEnumerable<IDictionary<FacePart, IEnumerable<FacePoint>>> FaceLandmark(I
results.AddRange(this._CustomFaceLandmarkDetector.GetLandmarks(landmarkTuples));
break;
default:
throw new ArgumentOutOfRangeException(nameof(model), model, null);
throw new ArgumentOutOfRangeException(nameof(predictorModel), predictorModel, null);
}
}
finally
Expand Down Expand Up @@ -879,16 +888,19 @@ public HeadPose PredictHeadPose(IDictionary<FacePart, IEnumerable<FacePoint>> la

#region Helpers

private IEnumerable<FullObjectDetection> RawFaceLandmarks(Image faceImage, IEnumerable<Location> faceLocations = null, PredictorModel model = PredictorModel.Large)
private IEnumerable<FullObjectDetection> RawFaceLandmarks(Image faceImage,
IEnumerable<Location> faceLocations = null,
PredictorModel predictorModel = PredictorModel.Large,
Model model = Model.Hog)
{
IEnumerable<MModRect> tmp;

if (faceLocations == null)
tmp = this.RawFaceLocations(faceImage);
tmp = this.RawFaceLocations(faceImage, 1, model);
else
tmp = faceLocations.Select(l => new MModRect { Rect = new Rectangle { Bottom = l.Bottom, Left = l.Left, Top = l.Top, Right = l.Right } });

if (model == PredictorModel.Custom)
if (predictorModel == PredictorModel.Custom)
{
foreach (var rect in tmp)
{
Expand All @@ -902,7 +914,7 @@ private IEnumerable<FullObjectDetection> RawFaceLandmarks(Image faceImage, IEnum
else
{
var posePredictor = this._PosePredictor68Point;
switch (model)
switch (predictorModel)
{
case PredictorModel.Small:
posePredictor = this._PosePredictor5Point;
Expand Down
10 changes: 6 additions & 4 deletions src/FaceRecognitionDotNet/docs/FaceRecognitionDotNet.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading