Skip to content

Commit 457da82

Browse files
Merge branch 'release/latest'
2 parents 0ea490a + e15029a commit 457da82

File tree

101 files changed

+8534
-1662
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+8534
-1662
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,3 +304,7 @@ __pycache__/
304304
*.btm.cs
305305
*.odx.cs
306306
*.xsd.cs
307+
308+
# Custom
309+
src/DlibDotNet.Native/*.bat
310+
src/DlibDotNet.Native.Dnn/*.bat

DebugTestSettings.testsettings

Lines changed: 0 additions & 22 deletions
This file was deleted.

DlibDotNet.sln

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ EndProject
1212
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DlibDotNet", "src\DlibDotNet\DlibDotNet.csproj", "{B13A6288-7B69-4B53-9138-2E20A8D5CFC5}"
1313
EndProject
1414
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{725DA5C9-9A1B-49BC-8F19-2A403753D8E8}"
15-
ProjectSection(SolutionItems) = preProject
16-
DebugTestSettings.testsettings = DebugTestSettings.testsettings
17-
ReleaseTestSettings.testsettings = ReleaseTestSettings.testsettings
18-
EndProjectSection
1915
EndProject
2016
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{19C83FDC-2BC9-42D6-9F51-3A0B822FABAD}"
2117
EndProject
@@ -59,6 +55,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaceLandmarkDetection", "ex
5955
EndProject
6056
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DlibDotNet.Extensions.Tests", "test\DlibDotNet.Extensions.Tests\DlibDotNet.Extensions.Tests.csproj", "{2A75C8B3-5122-4E7E-A0CF-A0AD5FFA60B2}"
6157
EndProject
58+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DnnFaceRecognition", "examples\DnnFaceRecognition\DnnFaceRecognition.csproj", "{C6EFE2AC-63BD-4574-B4A1-9AC80CA5AD2E}"
59+
EndProject
60+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DnnMmodFaceDetection", "examples\DnnMmodFaceDetection\DnnMmodFaceDetection.csproj", "{A6302463-CC32-4060-B8DF-466479046038}"
61+
EndProject
62+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DnnSemanticSegmentation", "examples\DnnSemanticSegmentation\DnnSemanticSegmentation.csproj", "{4DF84F72-0995-44ED-AC0A-A07327F078A2}"
63+
EndProject
6264
Global
6365
GlobalSection(SolutionConfigurationPlatforms) = preSolution
6466
Debug|Any CPU = Debug|Any CPU
@@ -309,6 +311,42 @@ Global
309311
{2A75C8B3-5122-4E7E-A0CF-A0AD5FFA60B2}.ReleaseLinux|Any CPU.Build.0 = Release|Any CPU
310312
{2A75C8B3-5122-4E7E-A0CF-A0AD5FFA60B2}.ReleaseMac|Any CPU.ActiveCfg = ReleaseMac|Any CPU
311313
{2A75C8B3-5122-4E7E-A0CF-A0AD5FFA60B2}.ReleaseMac|Any CPU.Build.0 = ReleaseMac|Any CPU
314+
{C6EFE2AC-63BD-4574-B4A1-9AC80CA5AD2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
315+
{C6EFE2AC-63BD-4574-B4A1-9AC80CA5AD2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
316+
{C6EFE2AC-63BD-4574-B4A1-9AC80CA5AD2E}.DebugLinux|Any CPU.ActiveCfg = DebugLinux|Any CPU
317+
{C6EFE2AC-63BD-4574-B4A1-9AC80CA5AD2E}.DebugLinux|Any CPU.Build.0 = DebugLinux|Any CPU
318+
{C6EFE2AC-63BD-4574-B4A1-9AC80CA5AD2E}.DebugMac|Any CPU.ActiveCfg = DebugMac|Any CPU
319+
{C6EFE2AC-63BD-4574-B4A1-9AC80CA5AD2E}.DebugMac|Any CPU.Build.0 = DebugMac|Any CPU
320+
{C6EFE2AC-63BD-4574-B4A1-9AC80CA5AD2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
321+
{C6EFE2AC-63BD-4574-B4A1-9AC80CA5AD2E}.Release|Any CPU.Build.0 = Release|Any CPU
322+
{C6EFE2AC-63BD-4574-B4A1-9AC80CA5AD2E}.ReleaseLinux|Any CPU.ActiveCfg = ReleaseLinux|Any CPU
323+
{C6EFE2AC-63BD-4574-B4A1-9AC80CA5AD2E}.ReleaseLinux|Any CPU.Build.0 = ReleaseLinux|Any CPU
324+
{C6EFE2AC-63BD-4574-B4A1-9AC80CA5AD2E}.ReleaseMac|Any CPU.ActiveCfg = ReleaseMac|Any CPU
325+
{C6EFE2AC-63BD-4574-B4A1-9AC80CA5AD2E}.ReleaseMac|Any CPU.Build.0 = ReleaseMac|Any CPU
326+
{A6302463-CC32-4060-B8DF-466479046038}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
327+
{A6302463-CC32-4060-B8DF-466479046038}.Debug|Any CPU.Build.0 = Debug|Any CPU
328+
{A6302463-CC32-4060-B8DF-466479046038}.DebugLinux|Any CPU.ActiveCfg = DebugLinux|Any CPU
329+
{A6302463-CC32-4060-B8DF-466479046038}.DebugLinux|Any CPU.Build.0 = DebugLinux|Any CPU
330+
{A6302463-CC32-4060-B8DF-466479046038}.DebugMac|Any CPU.ActiveCfg = DebugMac|Any CPU
331+
{A6302463-CC32-4060-B8DF-466479046038}.DebugMac|Any CPU.Build.0 = DebugMac|Any CPU
332+
{A6302463-CC32-4060-B8DF-466479046038}.Release|Any CPU.ActiveCfg = Release|Any CPU
333+
{A6302463-CC32-4060-B8DF-466479046038}.Release|Any CPU.Build.0 = Release|Any CPU
334+
{A6302463-CC32-4060-B8DF-466479046038}.ReleaseLinux|Any CPU.ActiveCfg = ReleaseLinux|Any CPU
335+
{A6302463-CC32-4060-B8DF-466479046038}.ReleaseLinux|Any CPU.Build.0 = ReleaseLinux|Any CPU
336+
{A6302463-CC32-4060-B8DF-466479046038}.ReleaseMac|Any CPU.ActiveCfg = ReleaseMac|Any CPU
337+
{A6302463-CC32-4060-B8DF-466479046038}.ReleaseMac|Any CPU.Build.0 = ReleaseMac|Any CPU
338+
{4DF84F72-0995-44ED-AC0A-A07327F078A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
339+
{4DF84F72-0995-44ED-AC0A-A07327F078A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
340+
{4DF84F72-0995-44ED-AC0A-A07327F078A2}.DebugLinux|Any CPU.ActiveCfg = DebugLinux|Any CPU
341+
{4DF84F72-0995-44ED-AC0A-A07327F078A2}.DebugLinux|Any CPU.Build.0 = DebugLinux|Any CPU
342+
{4DF84F72-0995-44ED-AC0A-A07327F078A2}.DebugMac|Any CPU.ActiveCfg = DebugMac|Any CPU
343+
{4DF84F72-0995-44ED-AC0A-A07327F078A2}.DebugMac|Any CPU.Build.0 = DebugMac|Any CPU
344+
{4DF84F72-0995-44ED-AC0A-A07327F078A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
345+
{4DF84F72-0995-44ED-AC0A-A07327F078A2}.Release|Any CPU.Build.0 = Release|Any CPU
346+
{4DF84F72-0995-44ED-AC0A-A07327F078A2}.ReleaseLinux|Any CPU.ActiveCfg = ReleaseLinux|Any CPU
347+
{4DF84F72-0995-44ED-AC0A-A07327F078A2}.ReleaseLinux|Any CPU.Build.0 = ReleaseLinux|Any CPU
348+
{4DF84F72-0995-44ED-AC0A-A07327F078A2}.ReleaseMac|Any CPU.ActiveCfg = ReleaseMac|Any CPU
349+
{4DF84F72-0995-44ED-AC0A-A07327F078A2}.ReleaseMac|Any CPU.Build.0 = ReleaseMac|Any CPU
312350
EndGlobalSection
313351
GlobalSection(SolutionProperties) = preSolution
314352
HideSolutionNode = FALSE
@@ -336,6 +374,9 @@ Global
336374
{1523DA42-DB7E-47B5-8AE6-305100F3891B} = {4082257D-FC8E-4D37-8489-89AAFC9D4A38}
337375
{9575AC94-3760-483F-9403-A77E7CFE8F47} = {5452AAEA-A679-4056-A2F7-8B6F8137CCAC}
338376
{2A75C8B3-5122-4E7E-A0CF-A0AD5FFA60B2} = {44730D39-C672-4CC0-B983-26CC9D7E59C1}
377+
{C6EFE2AC-63BD-4574-B4A1-9AC80CA5AD2E} = {19C83FDC-2BC9-42D6-9F51-3A0B822FABAD}
378+
{A6302463-CC32-4060-B8DF-466479046038} = {19C83FDC-2BC9-42D6-9F51-3A0B822FABAD}
379+
{4DF84F72-0995-44ED-AC0A-A07327F078A2} = {19C83FDC-2BC9-42D6-9F51-3A0B822FABAD}
339380
EndGlobalSection
340381
GlobalSection(ExtensibilityGlobals) = postSolution
341382
SolutionGuid = {9D3A508A-1F0B-4364-9FEC-16AF376DA11D}

ReleaseTestSettings.testsettings

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp2.0</TargetFramework>
6+
<Authors>Takuya Takeuchi</Authors>
7+
<Description>Sample of DlibDotNet</Description>
8+
<Company />
9+
<Configurations>Debug;Release;DebugLinux;ReleaseLinux;DebugMac;ReleaseMac</Configurations>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<ProjectReference Include="..\..\src\DlibDotNet\DlibDotNet.csproj" />
14+
</ItemGroup>
15+
16+
</Project>
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/*
2+
* This sample program is ported by C# from examples\dnn_face_recognition_ex.cpp.
3+
*/
4+
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Linq;
8+
using DlibDotNet;
9+
10+
namespace DnnFaceRecognition
11+
{
12+
13+
internal class Program
14+
{
15+
16+
private static void Main(string[] args)
17+
{
18+
if (args.Length != 1)
19+
{
20+
Console.WriteLine("Run this example by invoking it like this: ");
21+
Console.WriteLine(" ./DnnFaceRecognition faces/bald_guys.jpg");
22+
Console.WriteLine("You will also need to get the face landmarking model file as well as ");
23+
Console.WriteLine("the face recognition model file. Download and then decompress these files from: ");
24+
Console.WriteLine("http://dlib.net/files/shape_predictor_5_face_landmarks.dat.bz2");
25+
Console.WriteLine("http://dlib.net/files/dlib_face_recognition_resnet_model_v1.dat.bz2");
26+
return;
27+
}
28+
29+
// The first thing we are going to do is load all our models. First, since we need to
30+
// find faces in the image we will need a face detector:
31+
using (var detector = FrontalFaceDetector.GetFrontalFaceDetector())
32+
// We will also use a face landmarking model to align faces to a standard pose: (see face_landmark_detection_ex.cpp for an introduction)
33+
using (var sp = new ShapePredictor("shape_predictor_5_face_landmarks.dat"))
34+
// And finally we load the DNN responsible for face recognition.
35+
using (var net = DlibDotNet.Dnn.LossMetric.Deserialize("dlib_face_recognition_resnet_model_v1.dat"))
36+
37+
using (var img = Dlib.LoadImage<RgbPixel>(args[0]))
38+
using (var mat = new Matrix<RgbPixel>(img))
39+
40+
// Display the raw image on the screen
41+
using (var win = new ImageWindow(img))
42+
{
43+
// Run the face detector on the image of our action heroes, and for each face extract a
44+
// copy that has been normalized to 150x150 pixels in size and appropriately rotated
45+
// and centered.
46+
var faces = new List<Matrix<RgbPixel>>();
47+
foreach (var face in detector.Detect(img))
48+
{
49+
var shape = sp.Detect(img, face);
50+
var faceChipDetail = Dlib.GetFaceChipDetails(shape, 150, 0.25);
51+
var faceChip = Dlib.ExtractImageChip<RgbPixel>(mat, faceChipDetail);
52+
53+
//faces.Add(move(face_chip));
54+
faces.Add(faceChip);
55+
56+
// Also put some boxes on the faces so we can see that the detector is finding
57+
// them.
58+
win.AddOverlay(face);
59+
}
60+
61+
if (!faces.Any())
62+
{
63+
Console.WriteLine("No faces found in image!");
64+
return;
65+
}
66+
67+
// This call asks the DNN to convert each face image in faces into a 128D vector.
68+
// In this 128D vector space, images from the same person will be close to each other
69+
// but vectors from different people will be far apart. So we can use these vectors to
70+
// identify if a pair of images are from the same person or from different people.
71+
var faceDescriptors = net.Operator(faces);
72+
73+
// In particular, one simple thing we can do is face clustering. This next bit of code
74+
// creates a graph of connected faces and then uses the Chinese whispers graph clustering
75+
// algorithm to identify how many people there are and which faces belong to whom.
76+
var edges = new List<SamplePair>();
77+
for (uint i = 0; i < faceDescriptors.Count; ++i)
78+
{
79+
for (var j = i; j < faceDescriptors.Count; ++j)
80+
{
81+
// Faces are connected in the graph if they are close enough. Here we check if
82+
// the distance between two face descriptors is less than 0.6, which is the
83+
// decision threshold the network was trained to use. Although you can
84+
// certainly use any other threshold you find useful.
85+
var diff = faceDescriptors[i] - faceDescriptors[j];
86+
if (Dlib.Length(diff) < 0.6)
87+
edges.Add(new SamplePair(i, j));
88+
}
89+
}
90+
91+
Dlib.ChineseWhispers(edges, 100, out var numClusters, out var labels);
92+
93+
// This will correctly indicate that there are 4 people in the image.
94+
Console.WriteLine($"number of people found in the image: {numClusters}");
95+
96+
// Now let's display the face clustering results on the screen. You will see that it
97+
// correctly grouped all the faces.
98+
var winClusters = new List<ImageWindow>();
99+
for (var i = 0; i < numClusters; i++)
100+
winClusters.Add(new ImageWindow());
101+
var tileImages = new List<Matrix<RgbPixel>>();
102+
for (var clusterId = 0ul; clusterId < numClusters; ++clusterId)
103+
{
104+
var temp = new List<Matrix<RgbPixel>>();
105+
for (var j = 0; j < labels.Length; ++j)
106+
{
107+
if (clusterId == labels[j])
108+
temp.Add(faces[j]);
109+
}
110+
111+
winClusters[(int)clusterId].Title = $"face cluster {clusterId}";
112+
var tileImage = Dlib.TileImages(temp);
113+
tileImages.Add(tileImage);
114+
winClusters[(int)clusterId].SetImage(tileImage);
115+
}
116+
117+
// Finally, let's print one of the face descriptors to the screen.
118+
using (var trans = Dlib.Trans(faceDescriptors[0]))
119+
{
120+
Console.WriteLine($"face descriptor for one face: {trans}");
121+
122+
// It should also be noted that face recognition accuracy can be improved if jittering
123+
// is used when creating face descriptors. In particular, to get 99.38% on the LFW
124+
// benchmark you need to use the jitter_image() routine to compute the descriptors,
125+
// like so:
126+
var jitterImages = JitterImage(faces[0]).ToArray();
127+
var ret = net.Operator(jitterImages);
128+
using (var m = Dlib.Mat(ret))
129+
using (var faceDescriptor = Dlib.Mean<float>(m))
130+
using (var t = Dlib.Trans(faceDescriptor))
131+
{
132+
Console.WriteLine($"jittered face descriptor for one face: {t}");
133+
134+
// If you use the model without jittering, as we did when clustering the bald guys, it
135+
// gets an accuracy of 99.13% on the LFW benchmark. So jittering makes the whole
136+
// procedure a little more accurate but makes face descriptor calculation slower.
137+
138+
Console.WriteLine("hit enter to terminate");
139+
Console.ReadKey();
140+
141+
foreach (var jitterImage in jitterImages)
142+
jitterImage.Dispose();
143+
144+
foreach (var tileImage in tileImages)
145+
tileImage.Dispose();
146+
147+
foreach (var edge in edges)
148+
edge.Dispose();
149+
150+
foreach (var descriptor in faceDescriptors)
151+
descriptor.Dispose();
152+
153+
foreach (var face in faces)
154+
face.Dispose();
155+
}
156+
}
157+
}
158+
}
159+
160+
private static IEnumerable<Matrix<RgbPixel>> JitterImage(Matrix<RgbPixel> img)
161+
{
162+
// All this function does is make 100 copies of img, all slightly jittered by being
163+
// zoomed, rotated, and translated a little bit differently. They are also randomly
164+
// mirrored left to right.
165+
var rnd = new Rand();
166+
167+
var crops = new List<Matrix<RgbPixel>>();
168+
for (var i = 0; i< 100; ++i)
169+
crops.Add(Dlib.JitterImage(img, rnd));
170+
171+
return crops;
172+
}
173+
174+
}
175+
176+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# DNN Face Recognition
2+
3+
This program is ported by C# from examples\dnn_face_recognition_ex.cpp.
4+
5+
## How to use?
6+
7+
## 1. Build
8+
9+
1. Open command prompt and change to &lt;DnnFaceRecognition_dir&gt;
10+
1. Type the following command
11+
````
12+
dotnet build -c Release
13+
````
14+
2. Copy ***DlibDotNet.dll***, ***DlibDotNet.Native.dll*** and ***DlibDotNet.Native.Dnn.dll*** to output directory; &lt;DnnFaceRecognition_dir&gt;\bin\Release\netcoreapp2.0.
15+
16+
**NOTE**
17+
- You should build ***DlibDotNet.Native.dll*** and ***DlibDotNet.Native.Dnn.dll*** with CUDA.
18+
- If you want to run at Linux and MacOS, you should build the **DlibDotNet** at first.
19+
Please refer the [Tutorial for Linux](https://github.com/takuya-takeuchi/DlibDotNet/wiki/Tutorial-for-Linux) or [Tutorial for MacOS](https://github.com/takuya-takeuchi/DlibDotNet/wiki/Tutorial-for-MacOS).
20+
21+
## 2. Download demo data
22+
23+
Download test data from the following urls.
24+
25+
- http://dlib.net/files/shape_predictor_5_face_landmarks.dat.bz2
26+
- http://dlib.net/files/dlib_face_recognition_resnet_model_v1.dat.bz2
27+
- &lt;dlib&gt;\examples\faces\bald_guys.jpg
28+
29+
And extract them and copy to extracted fiels to &lt;DnnFaceRecognition_dir&gt;.
30+
31+
## 3. Run
32+
33+
````
34+
cd <DnnFaceRecognition_dir>
35+
dotnet run --configuration Release bald_guys.jpg
36+
````
37+
38+
![All](images/all.png "All")
39+
40+
![All](images/0.png "All")
41+
42+
![All](images/1.png "All")
43+
44+
![All](images/2.png "All")
45+
46+
![All](images/3.png "All")
346 KB
Loading
347 KB
Loading
350 KB
Loading

0 commit comments

Comments
 (0)