Skip to content

Commit 771298c

Browse files
author
Riccardo Gallina
committed
Merge branch 'feat/support-dotnet' into 'develop'
Feature: support C#/.NET See merge request sertiscorp/mle/edge/oneml-bootcamp!33
2 parents e8bf295 + 05bda49 commit 771298c

File tree

12 files changed

+416
-9
lines changed

12 files changed

+416
-9
lines changed

.gitlab-ci.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,11 +317,26 @@ build-java-arm-linux-android:
317317
- android-env-check
318318
- mirror-pull
319319

320-
build-golang:
320+
build-golang-x86_64:
321321
extends: .base_build
322322
script:
323323
- ./build.sh -t x86_64 -go --clean
324324

325+
build-golang-x86_64-cuda:
326+
extends: .base_build_gpu
327+
script:
328+
- ./build.sh -t x86_64-cuda -go --clean
329+
330+
build-csharp-x86_64:
331+
extends: .base_build
332+
script:
333+
- ./build.sh -t x86_64 -cs --clean
334+
335+
build-csharp-x86_64-cuda:
336+
extends: .base_build_gpu
337+
script:
338+
- ./build.sh -t x86_64-cuda -cs --clean
339+
325340
update-github-pages:
326341
# NOTE: We publish the API doc to GitHub Pages by mirroring `gh-pages` branch from GitLab to GitHub.
327342
extends: .base_release

README.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ Introduction and sample apps to showcase `oneML` functionalities and possible us
5151
| Coming soon | `iOS` |
5252

5353
### What is `oneML`?
54-
`oneML` is a fully-fledged C++ SDK providing APIs for a number of different AI/ML applications. It can be deployed on any target (CPU, GPU, CUDA) and platform (Android, iOS, embedded Linux, Linux, Windows). Morveover, `oneML` library provides API bindings in other programming languages such as Java, Python, and Golang.
54+
`oneML` is a fully-fledged C++ SDK providing APIs for a number of different AI/ML applications. Potentially, it can be deployed on any target (CPU, GPU, CUDA) and platform (Android, iOS, embedded Linux, Linux, Windows). Morveover, `oneML` library provides API bindings in other programming languages such as Java, Python, C# and Golang.
5555

5656
### What can you do with this repository?
57-
This repository provides `oneML` library (community edition) and its example applications in 4 programming languages: C++, Java, Python, and Golang (for Linux only). In case of Android development, you can use `oneML`'s Java bindings.
57+
This repository provides `oneML` library (community edition) and its example applications in 4 programming languages: C++, Java, Python, C# and Golang (for Linux only). In case of Android development, you can use `oneML`'s Java bindings.
5858
Please feel free to open an issue on GitHub if you found any issue.
5959

6060
## Features
@@ -322,6 +322,11 @@ To build `Python` apps for `aarch64-linux-gnu` target:
322322
./build.sh -t aarch64-linux-gnu -py --clean
323323
```
324324

325+
To build `C#` apps for `x86_64` target:
326+
```bash
327+
./build.sh -t x86_64 -cs --clean
328+
```
329+
325330
To build `Java` apps for `x86_64` target:
326331
```bash
327332
./build.sh -t x86_64 -jni --clean
@@ -358,6 +363,7 @@ successfully:
358363
- `tar` to unpack some archives
359364
- CMake 3.17 or newer (for `C++` build only)
360365
- Python 3.6 or newer and `pip` (for `Python` build only)
366+
- `.NET6` (for `C#` build only)
361367
- JDK 1.8 (for `Java` build only)
362368
- Android Studio xxx (for `Android` build only)
363369
- Golang 1.15 (for `Golang` build only)
@@ -382,6 +388,11 @@ To build `Python` apps for `msvc-x64` target:
382388
build.bat -t msvc-x64 -py --clean
383389
```
384390

391+
To build `C#` apps for `msvc-x64` target:
392+
```batch
393+
build.bat -t msvc-x64 -cs --clean
394+
```
395+
385396
To build `Java` apps for `msvc-x64` target:
386397
```batch
387398
build.bat -t msvc-x64 -jni --clean
@@ -402,14 +413,15 @@ Currently `x86-64-cuda` target supports only Cuda 11.x runtime on Linux only. We
402413
For compute capabilities later than `7.5`, it might not work.
403414

404415
## API Reference
405-
- [C++/Java/Python APIs](https://sertiscorp.github.io/oneML-bootcamp)
416+
- [C++/Java/Python/C# APIs](https://sertiscorp.github.io/oneML-bootcamp)
406417
- [Golang APIs](https://sertiscorp.github.io/oneML-bootcamp/godoc)
407418

408419
## Usage
409420
It is possible to find more details about the usage in each programming language
410421
specific folder in `apps` folder. You can click on the following links:
411422
- [C++ apps](https://github.com/sertiscorp/oneML-bootcamp/tree/develop/apps/cpp)
412423
- [Python apps](https://github.com/sertiscorp/oneML-bootcamp/tree/develop/apps/python)
424+
- [C# apps](https://github.com/sertiscorp/oneML-bootcamp/tree/develop/apps/csharp)
413425
- [Java apps](https://github.com/sertiscorp/oneML-bootcamp/tree/develop/apps/java)
414426
- [Golang apps](https://github.com/sertiscorp/oneML-bootcamp/tree/develop/apps/golang)
415427

@@ -423,4 +435,4 @@ For all the applications, it is possible to set the LOG level of `oneML` by sett
423435
## Roadmap
424436
- Support `iOS`
425437
- Support Cuda 10.2
426-
- Support Golang on Windows
438+
- Support Golang on Windows

apps/csharp/FaceDetectorApp.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using OneML;
2+
3+
class FaceDetectorApp {
4+
static void Main(string[] args) {
5+
LicenseManager manager = new LicenseManager();
6+
manager.ActivateTrial();
7+
8+
FaceDetector detector = new FaceDetector(manager);
9+
Utils utils = new Utils(manager);
10+
11+
string basePath = @"../../assets/images/";
12+
string path = basePath + @"face-detect-set/face/0.jpg";
13+
Image image = utils.ReadImageCV(path);
14+
FaceDetectorResult result = detector.Detect(image);
15+
Console.WriteLine("Faces: " + result.GetSize());
16+
17+
ScoreList scores = result.GetScores();
18+
BBoxList bboxes = result.GetBBoxes();
19+
Landmark5List landmarks = result.GetLandmarks();
20+
FacePoseList poses = result.GetPoses();
21+
StatusCodeList statuses = result.GetReturnStatus();
22+
23+
string precision = "F6";
24+
for (int i = 0; i < result.GetSize(); i++) {
25+
Console.WriteLine("Face " + i);
26+
Console.WriteLine("status: " + statuses[i]);
27+
Console.WriteLine("Score: " + scores[i].ToString(precision));
28+
Console.WriteLine("Pose: " + poses[i]);
29+
30+
BBox box = bboxes[i];
31+
string boxString = "BBox: [(" + box.top.ToString(precision) + ", " + box.left.ToString(precision) + ", " + box.bottom.ToString(precision) + ", " + box.right.ToString(precision) + ")]";
32+
Console.WriteLine(boxString);
33+
34+
Landmark5 landmark = landmarks[i];
35+
for (int j = 0; j < Face.GetLandmarkSize(); j++) {
36+
Console.WriteLine("Landmark " + j + ": (" + landmark.x[j].ToString(precision) + ", " + landmark.y[j].ToString(precision) + ")");
37+
}
38+
}
39+
}
40+
}

apps/csharp/FaceEmbedderApp.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using OneML;
2+
3+
class FaceEmbedderApp {
4+
static void PrintEmbedding(FaceEmbedderResult result) {
5+
Embedding emb = result.GetEmbedding();
6+
Console.WriteLine("Embedding size: " + emb.Count());
7+
8+
string precision = "F6";
9+
string embSample = "[";
10+
float embSum = 0;
11+
for (int i = 0; i < emb.Count(); i++) {
12+
if (i < 5) {
13+
embSample += emb[i].ToString(precision) + ", ";
14+
}
15+
embSum += emb[i];
16+
}
17+
embSample = embSample.Substring(0, embSample.Length-2) + "]";
18+
19+
Console.WriteLine("Embedding sample: " + embSample);
20+
Console.WriteLine("Embedding sum: " + embSum.ToString("F4"));
21+
Console.WriteLine("status: " + result.GetReturnStatus());
22+
}
23+
24+
static void Main(string[] args) {
25+
LicenseManager manager = new LicenseManager();
26+
manager.ActivateTrial();
27+
28+
FaceEmbedder embedder = new FaceEmbedder(manager);
29+
Utils utils = new Utils(manager);
30+
31+
string basePath = @"../../assets/images/";
32+
string path = basePath + @"register-set/Colin_Powell/colin_powell_0074.jpg";
33+
Image img = utils.ReadImageCV(path);
34+
FaceEmbedderResult result1 = embedder.Embed(img);
35+
Console.WriteLine("Original Embedding");
36+
PrintEmbedding(result1);
37+
38+
FaceEmbedderResult result2 = embedder.Embed(img, true);
39+
Console.WriteLine("Flipped Image Embedding");
40+
PrintEmbedding(result2);
41+
}
42+
}

apps/csharp/FaceIdApp.cs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using OneML;
2+
3+
class FaceIdApp {
4+
static void Print(FaceIdResult result) {
5+
string precision = "F6";
6+
Console.WriteLine("status: " + result.GetReturnStatus());
7+
Console.WriteLine("Is identifiable: " + BooleanToInt(result.IsIdentifiable()));
8+
Console.WriteLine("Id: " + result.GetId());
9+
Console.WriteLine("Nearest node distance: " + result.GetNearestNodeDistance().ToString(precision));
10+
Console.WriteLine("Combined distance: " + result.GetCombinedDistance().ToString(precision));
11+
}
12+
13+
static void Print(FaceIdResultList results) {
14+
foreach (FaceIdResult result in results) {
15+
Print(result);
16+
}
17+
}
18+
19+
static int BooleanToInt(bool val) {
20+
return val ? 1 : 0;
21+
}
22+
23+
static void Main(string[] args) {
24+
LicenseManager manager = new LicenseManager();
25+
manager.ActivateTrial();
26+
27+
FaceEmbedder embedder = new FaceEmbedder(manager);
28+
FaceId faceId = new FaceId(embedder, manager);
29+
Utils utils = new Utils(manager);
30+
31+
string basePath = @"../../assets/images";
32+
33+
string path1 = basePath + @"/register-set/Colin_Powell/colin_powell_0074.jpg";
34+
Image img1 = utils.ReadImageCV(path1);
35+
36+
string path2 = basePath + @"/register-set/Colin_Powell/colin_powell_0078.jpg";
37+
Image img2 = utils.ReadImageCV(path2);
38+
39+
string path3 = basePath + @"/register-set/George_Robertson/george_robertson_0000.jpg";
40+
Image img3 = utils.ReadImageCV(path3);
41+
42+
string path4 = basePath + @"/register-set/George_Robertson/george_robertson_0002.jpg";
43+
Image img4 = utils.ReadImageCV(path4);
44+
45+
// isTheSamePerson
46+
bool same1 = faceId.IsTheSamePerson(img1, img2);
47+
Console.WriteLine("Is the same person: " + BooleanToInt(same1));
48+
49+
FaceEmbedderResult result = embedder.Embed(img1);
50+
SamePersonResult sameResult = faceId.IsTheSamePerson(result.GetEmbedding(), img2);
51+
Console.WriteLine("Is the same person: " + BooleanToInt(sameResult.first));
52+
53+
// registerId
54+
int size1 = faceId.RegisterId("Colin_Powell", result.GetEmbedding());
55+
Console.WriteLine("Registered size is: " + size1);
56+
57+
Embedding emb = faceId.RegisterId("George_Robertson", img3);
58+
string embSample = "[";
59+
for (int i = 0; i < 5; i++) {
60+
embSample += emb[i].ToString("F6") + ", ";
61+
}
62+
embSample = embSample.Substring(0, embSample.Length-2) + "]";
63+
Console.WriteLine("Registered emb is: " + embSample);
64+
65+
// predict
66+
Print(faceId.Predict(img2));
67+
68+
// updateEmbeddingDynamically
69+
faceId.UpdateEmbeddingDynamically("George_Robertson", img3, emb);
70+
Print(faceId.Predict(img4));
71+
72+
faceId.UpdateEmbeddingDynamically("Colin_Powell", sameResult.second, result.GetEmbedding());
73+
74+
Print(faceId.Predict(img1));
75+
76+
// updateEmbedding
77+
faceId.UpdateEmbedding("George_Robertson", emb);
78+
Print(faceId.Predict(img3));
79+
80+
// removeId
81+
faceId.RemoveId("George_Robertson");
82+
faceId.RemoveId("Colin_Powell");
83+
84+
// getIds
85+
IdList idList = faceId.GetIds();
86+
Console.WriteLine("Gallery size: " + idList.Count());
87+
}
88+
}

apps/csharp/FaceVerificationApp.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using OneML;
2+
3+
class FaceVerificationApp {
4+
static int BooleanToInt(bool val) {
5+
return val ? 1 : 0;
6+
}
7+
8+
static void Main(string[] args) {
9+
LicenseManager manager = new LicenseManager();
10+
manager.ActivateKey();
11+
12+
FaceEmbedder embedder = new FaceEmbedder(manager);
13+
FaceDetector detector = new FaceDetector(manager);
14+
FaceId faceId = new FaceId(embedder, manager);
15+
Utils utils = new Utils(manager);
16+
17+
string basePath = @"../../assets/images";
18+
string file1 = basePath + @"/register-set/Colin_Powell/colin_powell_0074.jpg";
19+
string file2 = basePath + @"/evaluate-set/Colin_Powell/colin_powell_0097.jpg";
20+
string file3 = basePath + @"/register-set/George_Robertson/george_robertson_0000.jpg";
21+
string file4 = basePath + @"/evaluate-set/George_Robertson/george_robertson_0009.jpg";
22+
23+
Image img1 = utils.ReadImageCV(file1);
24+
Image img2 = utils.ReadImageCV(file2);
25+
Image img3 = utils.ReadImageCV(file3);
26+
Image img4 = utils.ReadImageCV(file4);
27+
28+
ImageBatch registerBatch = new ImageBatch();
29+
registerBatch.Add(img1);
30+
registerBatch.Add(img3);
31+
32+
ImageBatch evalBatch = new ImageBatch();
33+
evalBatch.Add(img2);
34+
evalBatch.Add(img4);
35+
36+
FaceDetectorResultList registerResults = detector.Detect(registerBatch);
37+
FaceDetectorResultList evalResults = detector.Detect(evalBatch);
38+
39+
Image alignImg1 = utils.CropAlignFaceLandmark(img1, registerResults[0].GetLandmarks()[0]);
40+
Image alignImg3 = utils.CropAlignFaceLandmark(img3, registerResults[1].GetLandmarks()[0]);
41+
Image alignImg2 = utils.CropAlignFaceLandmark(img2, evalResults[0].GetLandmarks()[0]);
42+
Image alignImg4 = utils.CropAlignFaceLandmark(img4, evalResults[1].GetLandmarks()[0]);
43+
44+
faceId.RegisterId("colin_powell", alignImg1);
45+
faceId.RegisterId("george_robertson", alignImg3);
46+
47+
ImageBatch predictBatch = new ImageBatch();
48+
predictBatch.Add(alignImg2);
49+
predictBatch.Add(alignImg4);
50+
FaceIdResultList results = faceId.Predict(predictBatch);
51+
52+
// Run with registration & predict style to print scores for validating with other language applications
53+
// since isTheSamePerson API doesn't provide any score.
54+
string precision = "F8";
55+
Console.WriteLine("First person nearest node distance: " + results[0].GetNearestNodeDistance().ToString(precision));
56+
Console.WriteLine("Second person nearest node distance: " + results[1].GetNearestNodeDistance().ToString(precision));
57+
Console.WriteLine("First person: " + results[0].GetId());
58+
Console.WriteLine("Second person: " + results[1].GetId());
59+
60+
// Also test the actual face verification API (IsTheSamePerson)
61+
bool same1 = faceId.IsTheSamePerson(img1, img2);
62+
Console.WriteLine("Is the same person (colin_powell): " + BooleanToInt(same1));
63+
64+
bool same2 = faceId.IsTheSamePerson(img3, img4);
65+
Console.WriteLine("Is the same person (george_robertson): " + BooleanToInt(same2));
66+
}
67+
}

apps/csharp/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# C# sample application
2+
Source code for the applications in C# programming language.
3+
4+
## How to run
5+
Set up environment variables. Add a folder which contains `liboneml.so` to `LD_LIBRARY_PATH`. Replace `<target_arch>` with your target architecture.
6+
```
7+
export LD_LIBRARY_PATH="/path/to/oneml-bootcamp/assets/binaries/<target_arch>/lib:$LD_LIBRARY_PATH"
8+
```
9+
For example,
10+
```
11+
export LD_LIBRARY_PATH="/workspace/oneml-bootcamp/assets/binaries/x86_64/lib:$LD_LIBRARY_PATH"
12+
```
13+
14+
Run the app:
15+
```
16+
dotnet new console -o MyApp
17+
cd MyApp
18+
cp ../<app_name>.cs Program.cs
19+
dotnet run
20+
```
21+
22+
Or:
23+
```
24+
dotnet new console -o MyApp
25+
cd MyApp
26+
cp ../<app_name>.cs Program.cs
27+
dotnet build
28+
bin/Debug/net6.0/MyApp
29+
```

0 commit comments

Comments
 (0)