Skip to content

Commit 874895e

Browse files
committed
update 1.4.1
1 parent 8e05aad commit 874895e

File tree

49 files changed

+14674
-8654
lines changed

Some content is hidden

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

49 files changed

+14674
-8654
lines changed

Assets/DlibFaceLandmarkDetector/Examples/BenchmarkExample/BenchmarkExample.cs

Lines changed: 148 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
using DlibFaceLandmarkDetector;
22
using DlibFaceLandmarkDetector.UnityUtils;
33
using System;
4-
using System.Collections;
54
using System.Collections.Generic;
5+
using System.Threading;
66
using UnityEngine;
77
using UnityEngine.SceneManagement;
8+
using UnityEngine.UI;
89

910
namespace DlibFaceLandmarkDetectorExample
1011
{
@@ -13,6 +14,14 @@ namespace DlibFaceLandmarkDetectorExample
1314
/// </summary>
1415
public class BenchmarkExample : MonoBehaviour
1516
{
17+
[Header("Output")]
18+
/// <summary>
19+
/// The RawImage for previewing the result.
20+
/// </summary>
21+
public RawImage resultPreview;
22+
23+
[Space(10)]
24+
1625
/// <summary>
1726
/// The number of benchmark times.
1827
/// </summary>
@@ -44,29 +53,35 @@ public class BenchmarkExample : MonoBehaviour
4453
/// </summary>
4554
FpsMonitor fpsMonitor;
4655

47-
#if UNITY_WEBGL
48-
IEnumerator getFilePath_Coroutine;
49-
#endif
56+
/// <summary>
57+
/// The CancellationTokenSource.
58+
/// </summary>
59+
CancellationTokenSource cts = new CancellationTokenSource();
60+
61+
public enum DetectMode
62+
{
63+
None,
64+
ValueTuple,
65+
NoAlloc
66+
}
5067

5168
// Use this for initialization
52-
void Start()
69+
async void Start()
5370
{
5471
fpsMonitor = GetComponent<FpsMonitor>();
5572

5673
dlibShapePredictorFileName = DlibFaceLandmarkDetectorExample.dlibShapePredictorFileName;
57-
#if UNITY_WEBGL
58-
getFilePath_Coroutine = Utils.getFilePathAsync(dlibShapePredictorFileName, (result) =>
59-
{
60-
getFilePath_Coroutine = null;
6174

62-
dlibShapePredictorFilePath = result;
63-
Run();
64-
});
65-
StartCoroutine(getFilePath_Coroutine);
66-
#else
67-
dlibShapePredictorFilePath = Utils.getFilePath(dlibShapePredictorFileName);
75+
// Asynchronously retrieves the readable file path from the StreamingAssets directory.
76+
if (fpsMonitor != null)
77+
fpsMonitor.consoleText = "Preparing file access...";
78+
79+
dlibShapePredictorFilePath = await Utils.getFilePathAsyncTask(dlibShapePredictorFileName, cancellationToken: cts.Token);
80+
81+
if (fpsMonitor != null)
82+
fpsMonitor.consoleText = "";
83+
6884
Run();
69-
#endif
7085
}
7186

7287
private void Run()
@@ -83,22 +98,33 @@ private void Run()
8398
+ " If you want to draw the result correctly, we recommend using the OpenCVForUnityUtils.DrawFaceLandmark method.");
8499
}
85100

86-
private void StartBenchmark(Texture2D targetImg, FaceLandmarkDetector detector, int times = 100, bool noAlloc = false)
101+
private void StartBenchmark(Texture2D targetImg, FaceLandmarkDetector detector, int times = 100, DetectMode detectMode = DetectMode.None)
87102
{
88-
string result = noAlloc ? BenchmarkNoGCAlloc(targetImg, detector, times) : Benchmark(targetImg, detector, times);
89-
Debug.Log(result);
90-
if (fpsMonitor != null)
103+
string result = null;
104+
switch (detectMode)
91105
{
92-
fpsMonitor.consoleText = result;
106+
case DetectMode.None:
107+
result = Benchmark(targetImg, detector, times);
108+
Debug.Log(result);
109+
ShowImage(targetImg);
110+
break;
111+
case DetectMode.ValueTuple:
112+
result = BenchmarkValueTuple(targetImg, detector, times);
113+
Debug.Log(result);
114+
ShowImageValueTuple(targetImg);
115+
break;
116+
case DetectMode.NoAlloc:
117+
result = BenchmarkNoGCAlloc(targetImg, detector, times);
118+
Debug.Log(result);
119+
ShowImageNoGCAlloc(targetImg);
120+
break;
121+
default:
122+
break;
93123
}
94124

95-
if (noAlloc)
96-
{
97-
ShowImageNoGCAlloc(targetImg);
98-
}
99-
else
125+
if (fpsMonitor != null)
100126
{
101-
ShowImage(targetImg);
127+
fpsMonitor.consoleText = result;
102128
}
103129
}
104130

@@ -142,6 +168,46 @@ private string Benchmark(Texture2D targetImg, FaceLandmarkDetector detector, int
142168
return result;
143169
}
144170

171+
private string BenchmarkValueTuple(Texture2D targetImg, FaceLandmarkDetector detector, int times = 100)
172+
{
173+
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
174+
175+
string result = "sp_name: " + dlibShapePredictorFileName + "\n";
176+
result += "times: " + times + " (size: " + targetImg.width + "*" + targetImg.height + ")" + "\n";
177+
178+
detector.SetImage(targetImg);
179+
180+
// FaceLandmarkDetector.Detect() benchmark.
181+
sw.Start();
182+
UnityEngine.Profiling.Profiler.BeginSample("GCAllocTest: DetectValueTuple()");
183+
for (int i = 0; i < times; ++i)
184+
{
185+
detector.DetectValueTuple();
186+
}
187+
UnityEngine.Profiling.Profiler.EndSample();
188+
sw.Stop();
189+
result += " Detect(): " + sw.ElapsedMilliseconds + "ms" + " Avg:" + sw.ElapsedMilliseconds / times + "ms" + "\n";
190+
191+
192+
// FaceLandmarkDetector.DetectLandmark() benchmark.
193+
(double x, double y, double width, double height)[] detectResult = detector.DetectValueTuple();
194+
sw.Reset();
195+
sw.Start();
196+
UnityEngine.Profiling.Profiler.BeginSample("GCAllocTest: DetectLandmark()");
197+
for (int i = 0; i < times; ++i)
198+
{
199+
foreach (var rect in detectResult)
200+
{
201+
detector.DetectLandmark(rect);
202+
}
203+
}
204+
UnityEngine.Profiling.Profiler.EndSample();
205+
sw.Stop();
206+
result += " DetectLandmark(): " + sw.ElapsedMilliseconds + "ms" + " Avg:" + sw.ElapsedMilliseconds / times + "ms";
207+
208+
return result;
209+
}
210+
145211
private string BenchmarkNoGCAlloc(Texture2D targetImg, FaceLandmarkDetector detector, int times = 100)
146212
{
147213
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
@@ -169,7 +235,7 @@ private string BenchmarkNoGCAlloc(Texture2D targetImg, FaceLandmarkDetector dete
169235
UnityEngine.Profiling.Profiler.EndSample();
170236
sw.Stop();
171237
result += " Detect(): " + sw.ElapsedMilliseconds + "ms" + " Avg:" + sw.ElapsedMilliseconds / times + "ms" + "\n";
172-
238+
173239

174240
// FaceLandmarkDetector.DetectLandmark() benchmark.
175241
int detectLandmarkCount = detector.DetectLandmarkOnly(detectResult[0], detectResult[1], detectResult[2], detectResult[3]);
@@ -205,22 +271,6 @@ private void ShowImage(Texture2D texture2D)
205271
dstTexture2D.SetPixels32(texture2D.GetPixels32());
206272
dstTexture2D.Apply();
207273

208-
gameObject.transform.localScale = new Vector3(texture2D.width, texture2D.height, 1);
209-
210-
float width = gameObject.transform.localScale.x;
211-
float height = gameObject.transform.localScale.y;
212-
213-
float widthScale = (float)Screen.width / width;
214-
float heightScale = (float)Screen.height / height;
215-
if (widthScale < heightScale)
216-
{
217-
Camera.main.orthographicSize = (width * (float)Screen.height / (float)Screen.width) / 2;
218-
}
219-
else
220-
{
221-
Camera.main.orthographicSize = height / 2;
222-
}
223-
224274
faceLandmarkDetector.SetImage(texture2D);
225275

226276
//detect face rects
@@ -237,33 +287,46 @@ private void ShowImage(Texture2D texture2D)
237287
// draw face rect
238288
faceLandmarkDetector.DrawDetectResult(dstTexture2D, 255, 0, 0, 255, 2);
239289

240-
gameObject.GetComponent<Renderer>().material.mainTexture = dstTexture2D;
290+
resultPreview.texture = dstTexture2D;
291+
resultPreview.GetComponent<AspectRatioFitter>().aspectRatio = (float)dstTexture2D.width / dstTexture2D.height;
241292
}
242293

243-
private void ShowImageNoGCAlloc(Texture2D texture2D)
294+
private void ShowImageValueTuple(Texture2D texture2D)
244295
{
245296
if (dstTexture2D != null)
246297
Texture2D.Destroy(dstTexture2D);
247298
dstTexture2D = new Texture2D(texture2D.width, texture2D.height, texture2D.format, false);
248299
dstTexture2D.SetPixels32(texture2D.GetPixels32());
249300
dstTexture2D.Apply();
250301

251-
gameObject.transform.localScale = new Vector3(texture2D.width, texture2D.height, 1);
302+
faceLandmarkDetector.SetImage(texture2D);
252303

253-
float width = gameObject.transform.localScale.x;
254-
float height = gameObject.transform.localScale.y;
304+
//detect face rects
305+
(double x, double y, double width, double height)[] detectResult = faceLandmarkDetector.DetectValueTuple();
255306

256-
float widthScale = (float)Screen.width / width;
257-
float heightScale = (float)Screen.height / height;
258-
if (widthScale < heightScale)
259-
{
260-
Camera.main.orthographicSize = (width * (float)Screen.height / (float)Screen.width) / 2;
261-
}
262-
else
307+
foreach (var rect in detectResult)
263308
{
264-
Camera.main.orthographicSize = height / 2;
309+
//detect landmark points
310+
faceLandmarkDetector.DetectLandmark(rect);
311+
// draw landmark points
312+
faceLandmarkDetector.DrawDetectLandmarkResult(dstTexture2D, 0, 255, 0, 255);
265313
}
266314

315+
// draw face rect
316+
faceLandmarkDetector.DrawDetectResult(dstTexture2D, 255, 0, 0, 255, 2);
317+
318+
resultPreview.texture = dstTexture2D;
319+
resultPreview.GetComponent<AspectRatioFitter>().aspectRatio = (float)dstTexture2D.width / dstTexture2D.height;
320+
}
321+
322+
private void ShowImageNoGCAlloc(Texture2D texture2D)
323+
{
324+
if (dstTexture2D != null)
325+
Texture2D.Destroy(dstTexture2D);
326+
dstTexture2D = new Texture2D(texture2D.width, texture2D.height, texture2D.format, false);
327+
dstTexture2D.SetPixels32(texture2D.GetPixels32());
328+
dstTexture2D.Apply();
329+
267330
faceLandmarkDetector.SetImage(texture2D);
268331

269332
//detect face rects
@@ -294,7 +357,8 @@ private void ShowImageNoGCAlloc(Texture2D texture2D)
294357
// draw face rect
295358
faceLandmarkDetector.DrawDetectResult(dstTexture2D, 255, 0, 0, 255, 2);
296359

297-
gameObject.GetComponent<Renderer>().material.mainTexture = dstTexture2D;
360+
resultPreview.texture = dstTexture2D;
361+
resultPreview.GetComponent<AspectRatioFitter>().aspectRatio = (float)dstTexture2D.width / dstTexture2D.height;
298362
}
299363

300364
// Update is called once per frame
@@ -314,13 +378,8 @@ void OnDisable()
314378
if (faceLandmarkDetector != null)
315379
faceLandmarkDetector.Dispose();
316380

317-
#if UNITY_WEBGL
318-
if (getFilePath_Coroutine != null)
319-
{
320-
StopCoroutine(getFilePath_Coroutine);
321-
((IDisposable)getFilePath_Coroutine).Dispose();
322-
}
323-
#endif
381+
if (cts != null)
382+
cts.Dispose();
324383
}
325384

326385
/// <summary>
@@ -345,6 +404,28 @@ public void OnBenchmarkLargeImageButtonClick()
345404
StartBenchmark(largeImage, faceLandmarkDetector, times);
346405
}
347406

407+
/// <summary>
408+
/// Raises the benchmark small mage button click event.
409+
/// </summary>
410+
public void OnBenchmarkValueTupleSmallImageButtonClick()
411+
{
412+
if (faceLandmarkDetector == null)
413+
return;
414+
415+
StartBenchmark(smallImage, faceLandmarkDetector, times, DetectMode.ValueTuple);
416+
}
417+
418+
/// <summary>
419+
/// Raises the benchmark large image button click event.
420+
/// </summary>
421+
public void OnBenchmarkValueTupleLargeImageButtonClick()
422+
{
423+
if (faceLandmarkDetector == null)
424+
return;
425+
426+
StartBenchmark(largeImage, faceLandmarkDetector, times, DetectMode.ValueTuple);
427+
}
428+
348429
/// <summary>
349430
/// Raises the benchmark small mage button click event.
350431
/// </summary>
@@ -353,7 +434,7 @@ public void OnBenchmarkNoGCAllocSmallImageButtonClick()
353434
if (faceLandmarkDetector == null)
354435
return;
355436

356-
StartBenchmark(smallImage, faceLandmarkDetector, times, true);
437+
StartBenchmark(smallImage, faceLandmarkDetector, times, DetectMode.NoAlloc);
357438
}
358439

359440
/// <summary>
@@ -364,7 +445,7 @@ public void OnBenchmarkNoGCAllocLargeImageButtonClick()
364445
if (faceLandmarkDetector == null)
365446
return;
366447

367-
StartBenchmark(largeImage, faceLandmarkDetector, times, true);
448+
StartBenchmark(largeImage, faceLandmarkDetector, times, DetectMode.NoAlloc);
368449
}
369450

370451
/// <summary>

0 commit comments

Comments
 (0)