Skip to content

Commit 49b5320

Browse files
committed
Add FaceDetectorYN class and associated native methods for face detection
1 parent ecd814d commit 49b5320

File tree

6 files changed

+207
-0
lines changed

6 files changed

+207
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System.Diagnostics.Contracts;
2+
using System.Runtime.InteropServices;
3+
using OpenCvSharp.Dnn;
4+
5+
#pragma warning disable 1591
6+
#pragma warning disable CA1401 // P/Invokes should not be visible
7+
#pragma warning disable CA2101 // Specify marshalling for P-Invoke string arguments (code analysis)
8+
#pragma warning disable IDE1006 // Naming style
9+
10+
namespace OpenCvSharp.Internal;
11+
12+
public static partial class NativeMethods
13+
{
14+
[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
15+
internal static extern IntPtr cveFaceDetectorYNCreate(
16+
IntPtr model,
17+
IntPtr config,
18+
ref Size inputSize,
19+
float scoreThreshold,
20+
float nmsThreshold,
21+
int topK,
22+
Backend backendId,
23+
Target targetId,
24+
ref IntPtr sharedPtr
25+
);
26+
27+
[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
28+
internal static extern int cveFaceDetectorYNDetect(IntPtr faceDetector, IntPtr image, IntPtr faces);
29+
30+
[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
31+
internal static extern void cveFaceDetectorYNRelease(ref IntPtr faceDetector);
32+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using OpenCvSharp.Dnn;
2+
using OpenCvSharp.Internal;
3+
4+
namespace OpenCvSharp;
5+
6+
/// <summary>
7+
/// DNN-based face detector
8+
/// </summary>
9+
public class FaceDetectorYN : DisposableCvObject
10+
{
11+
/// <summary>
12+
/// A pointer to the shared pointer to the unmanaged object
13+
/// </summary>
14+
private IntPtr _sharedPtr;
15+
16+
/// <summary>
17+
/// Creates an instance of this class with given parameters.
18+
/// </summary>
19+
/// <param name="model">The path to the requested model</param>
20+
/// <param name="config">The path to the config file for compability, which is not requested for ONNX models</param>
21+
/// <param name="inputSize">The size of the input image</param>
22+
/// <param name="scoreThreshold">The threshold to filter out bounding boxes of score smaller than the given value</param>
23+
/// <param name="nmsThreshold">The threshold to suppress bounding boxes of IoU bigger than the given value</param>
24+
/// <param name="topK">Keep top K bboxes before NMS</param>
25+
/// <param name="backendId">The id of backend</param>
26+
/// <param name="targetId">The id of target device</param>
27+
public FaceDetectorYN(
28+
string model,
29+
string config,
30+
Size inputSize,
31+
float scoreThreshold = 0.9f,
32+
float nmsThreshold = 0.3f,
33+
int topK = 5000,
34+
Backend backendId = Backend.DEFAULT,
35+
Target targetId = Target.CPU)
36+
{
37+
using StdString csModel = new(model);
38+
using StdString csConfig = new(config);
39+
40+
ptr = NativeMethods.cveFaceDetectorYNCreate(
41+
csModel.CvPtr,
42+
csConfig.CvPtr,
43+
ref inputSize,
44+
scoreThreshold,
45+
nmsThreshold,
46+
topK,
47+
backendId,
48+
targetId,
49+
ref _sharedPtr
50+
);
51+
}
52+
53+
/// <summary>
54+
/// A simple interface to detect face from given image.
55+
/// </summary>
56+
/// <param name="image">An image to detect</param>
57+
/// <param name="faces">Detection results stored in a Mat</param>
58+
/// <returns>1 if detection is successful, 0 otherwise.</returns>
59+
public int Detect(Mat image, Mat faces)
60+
{
61+
using InputArray iaImage = new(image);
62+
using OutputArray oaFaces = new(faces);
63+
return NativeMethods.cveFaceDetectorYNDetect(ptr, iaImage.CvPtr, oaFaces.CvPtr);
64+
}
65+
66+
/// <summary>
67+
/// Release the unmanaged memory associated with this FaceDetectorYN
68+
/// </summary>
69+
protected override void DisposeUnmanaged()
70+
{
71+
if (!IntPtr.Zero.Equals(_sharedPtr))
72+
{
73+
NativeMethods.cveFaceDetectorYNRelease(ref _sharedPtr);
74+
_sharedPtr = IntPtr.Zero;
75+
}
76+
77+
base.DisposeUnmanaged();
78+
}
79+
}

src/OpenCvSharpExtern/OpenCvSharpExtern.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ copy "$(SolutionDir)opencv_files\opencv_win_x64\x64\vc17\bin\opencv_videoio_ffmp
236236
<ClCompile Include="dnn.cpp" />
237237
<ClCompile Include="dnn_superres.cpp" />
238238
<ClCompile Include="face.cpp" />
239+
<ClCompile Include="face_detector_yn.cpp" />
239240
<ClCompile Include="highgui.cpp" />
240241
<ClCompile Include="imgcodecs.cpp" />
241242
<ClCompile Include="imgproc.cpp" />
@@ -282,6 +283,7 @@ copy "$(SolutionDir)opencv_files\opencv_win_x64\x64\vc17\bin\opencv_videoio_ffmp
282283
<ClInclude Include="dnn.h" />
283284
<ClInclude Include="dnn_Net.h" />
284285
<ClInclude Include="dnn_superres.h" />
286+
<ClInclude Include="face_detector_yn.h" />
285287
<ClInclude Include="face_Facemark.h" />
286288
<ClInclude Include="face_FaceRecognizer.h" />
287289
<ClInclude Include="cuda.h" />

src/OpenCvSharpExtern/OpenCvSharpExtern.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@
103103
<ClCompile Include="barcode.cpp">
104104
<Filter>Source Files</Filter>
105105
</ClCompile>
106+
<ClCompile Include="face_detector_yn.cpp">
107+
<Filter>Source Files</Filter>
108+
</ClCompile>
106109
</ItemGroup>
107110
<ItemGroup>
108111
<ClInclude Include="bgsegm.h">
@@ -384,6 +387,9 @@
384387
<ClInclude Include="barcode.h">
385388
<Filter>Header Files</Filter>
386389
</ClInclude>
390+
<ClInclude Include="face_detector_yn.h">
391+
<Filter>Header Files\objdetect</Filter>
392+
</ClInclude>
387393
</ItemGroup>
388394
<ItemGroup>
389395
<Filter Include="Source Files">
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include "face_detector_yn.h"
2+
#include <opencv2/core/cvstd.hpp>
3+
#include <opencv2/core/cvstd_wrapper.hpp>
4+
#include <opencv2/core/mat.hpp>
5+
#include <opencv2/core/types_c.h>
6+
#include <opencv2/objdetect/face.hpp>
7+
#include <opencv2/opencv_modules.hpp>
8+
9+
cv::FaceDetectorYN* cveFaceDetectorYNCreate(
10+
cv::String* model,
11+
cv::String* config,
12+
CvSize* inputSize,
13+
float scoreThreshold,
14+
float nmsThreshold,
15+
int topK,
16+
int backendId,
17+
int targetId,
18+
cv::Ptr<cv::FaceDetectorYN>** sharedPtr)
19+
{
20+
#ifdef HAVE_OPENCV_OBJDETECT
21+
cv::Ptr<cv::FaceDetectorYN> ptr = cv::FaceDetectorYN::create(
22+
*model,
23+
*config,
24+
*inputSize,
25+
scoreThreshold,
26+
nmsThreshold,
27+
topK,
28+
backendId,
29+
targetId);
30+
*sharedPtr = new cv::Ptr<cv::FaceDetectorYN>(ptr);
31+
return (*sharedPtr)->get();
32+
#else
33+
throw_no_objdetect();
34+
#endif
35+
}
36+
37+
void cveFaceDetectorYNRelease(cv::Ptr<cv::FaceDetectorYN>** faceDetector)
38+
{
39+
#ifdef HAVE_OPENCV_OBJDETECT
40+
delete* faceDetector;
41+
*faceDetector = 0;
42+
#else
43+
throw_no_objdetect();
44+
#endif
45+
}
46+
47+
int cveFaceDetectorYNDetect(cv::FaceDetectorYN* faceDetetor, cv::_InputArray* image, cv::_OutputArray* faces)
48+
{
49+
#ifdef HAVE_OPENCV_OBJDETECT
50+
return faceDetetor->detect(*image, *faces);
51+
#else
52+
throw_no_objdetect();
53+
#endif
54+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#pragma once
2+
3+
#ifndef NO_OBJDETECT
4+
5+
// ReSharper disable IdentifierTypo
6+
// ReSharper disable CppInconsistentNaming
7+
// ReSharper disable CppNonInlineFunctionDefinitionInHeaderFile
8+
9+
#include "my_functions.h"
10+
#include <opencv2/core/cvstd.hpp>
11+
#include <opencv2/core/cvstd_wrapper.hpp>
12+
#include <opencv2/core/types_c.h>
13+
#include <opencv2/objdetect/face.hpp>
14+
15+
#ifndef _WINRT_DLL
16+
17+
CVAPI(cv::FaceDetectorYN*) cveFaceDetectorYNCreate(
18+
cv::String* model,
19+
cv::String* config,
20+
CvSize* inputSize,
21+
float scoreThreshold,
22+
float nmsThreshold,
23+
int topK,
24+
int backendId,
25+
int targetId,
26+
cv::Ptr<cv::FaceDetectorYN>** sharedPtr);
27+
28+
CVAPI(void) cveFaceDetectorYNRelease(cv::Ptr<cv::FaceDetectorYN>** faceDetector);
29+
30+
CVAPI(int) cveFaceDetectorYNDetect(cv::FaceDetectorYN* faceDetector, cv::_InputArray* image, cv::_OutputArray* faces);
31+
32+
#endif
33+
34+
#endif // NO_OBJDETECT

0 commit comments

Comments
 (0)