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
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using OpenCvSharp.Dnn;

#pragma warning disable 1591
#pragma warning disable CA1401 // P/Invokes should not be visible
#pragma warning disable CA2101 // Specify marshalling for P-Invoke string arguments (code analysis)
#pragma warning disable IDE1006 // Naming style

namespace OpenCvSharp.Internal;

public static partial class NativeMethods
{
[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern IntPtr cveFaceDetectorYNCreate(
IntPtr model,
IntPtr config,
ref Size inputSize,
float scoreThreshold,
float nmsThreshold,
int topK,
Backend backendId,
Target targetId,
ref IntPtr sharedPtr
);

[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern int cveFaceDetectorYNDetect(IntPtr faceDetector, IntPtr image, IntPtr faces);

[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern void cveFaceDetectorYNRelease(ref IntPtr faceDetector);
}
82 changes: 82 additions & 0 deletions src/OpenCvSharp/Modules/objdetect/FaceDetectorYN.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using OpenCvSharp.Dnn;
using OpenCvSharp.Internal;

namespace OpenCvSharp;

/// <summary>
/// DNN-based face detector
/// </summary>
public class FaceDetectorYN : DisposableCvObject
{
/// <summary>
/// A pointer to the shared pointer to the unmanaged object
/// </summary>
private IntPtr _sharedPtr;

/// <summary>
/// Creates an instance of this class with given parameters.
/// </summary>
/// <param name="model">The path to the requested model</param>
/// <param name="config">The path to the config file for compatibility, which is not requested for ONNX models</param>
/// <param name="inputSize">The size of the input image</param>
/// <param name="scoreThreshold">The threshold to filter out bounding boxes of score smaller than the given value</param>
/// <param name="nmsThreshold">The threshold to suppress bounding boxes of IoU bigger than the given value</param>
/// <param name="topK">Keep top K bboxes before NMS</param>
/// <param name="backendId">The id of backend</param>
/// <param name="targetId">The id of target device</param>
public FaceDetectorYN(
string model,
string config,
Size inputSize,
float scoreThreshold = 0.9f,
float nmsThreshold = 0.3f,
int topK = 5000,
Backend backendId = Backend.DEFAULT,
Target targetId = Target.CPU)
{
using StdString csModel = new(model);
using StdString csConfig = new(config);

ptr = NativeMethods.cveFaceDetectorYNCreate(
csModel.CvPtr,
csConfig.CvPtr,
ref inputSize,
scoreThreshold,
nmsThreshold,
topK,
backendId,
targetId,
ref _sharedPtr
);
}

/// <summary>
/// A simple interface to detect face from given image.
/// </summary>
/// <param name="image">An image to detect</param>
/// <param name="faces">Detection results stored in a Mat</param>
/// <returns>1 if detection is successful, 0 otherwise.</returns>
public int Detect(Mat image, Mat faces)
{
ThrowIfDisposed();
using InputArray iaImage = new(image);
using OutputArray oaFaces = new(faces);
int result = NativeMethods.cveFaceDetectorYNDetect(ptr, iaImage.CvPtr, oaFaces.CvPtr);
GC.KeepAlive(this);
return result;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/// <summary>
/// Release the unmanaged memory associated with this FaceDetectorYN
/// </summary>
protected override void DisposeUnmanaged()
{
if (!IntPtr.Zero.Equals(_sharedPtr))
{
NativeMethods.cveFaceDetectorYNRelease(ref _sharedPtr);
_sharedPtr = IntPtr.Zero;
}

base.DisposeUnmanaged();
}
}
2 changes: 2 additions & 0 deletions src/OpenCvSharpExtern/OpenCvSharpExtern.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ copy "$(SolutionDir)opencv_files\opencv_win_x64\x64\vc17\bin\opencv_videoio_ffmp
<ClCompile Include="dnn.cpp" />
<ClCompile Include="dnn_superres.cpp" />
<ClCompile Include="face.cpp" />
<ClCompile Include="face_detector_yn.cpp" />
<ClCompile Include="highgui.cpp" />
<ClCompile Include="imgcodecs.cpp" />
<ClCompile Include="imgproc.cpp" />
Expand Down Expand Up @@ -282,6 +283,7 @@ copy "$(SolutionDir)opencv_files\opencv_win_x64\x64\vc17\bin\opencv_videoio_ffmp
<ClInclude Include="dnn.h" />
<ClInclude Include="dnn_Net.h" />
<ClInclude Include="dnn_superres.h" />
<ClInclude Include="face_detector_yn.h" />
<ClInclude Include="face_Facemark.h" />
<ClInclude Include="face_FaceRecognizer.h" />
<ClInclude Include="cuda.h" />
Expand Down
6 changes: 6 additions & 0 deletions src/OpenCvSharpExtern/OpenCvSharpExtern.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@
<ClCompile Include="barcode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="face_detector_yn.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="bgsegm.h">
Expand Down Expand Up @@ -384,6 +387,9 @@
<ClInclude Include="barcode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="face_detector_yn.h">
<Filter>Header Files\objdetect</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Source Files">
Expand Down
54 changes: 54 additions & 0 deletions src/OpenCvSharpExtern/face_detector_yn.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "face_detector_yn.h"
#include <opencv2/core/cvstd.hpp>
#include <opencv2/core/cvstd_wrapper.hpp>
#include <opencv2/core/mat.hpp>
#include <opencv2/core/types_c.h>
#include <opencv2/objdetect/face.hpp>
#include <opencv2/opencv_modules.hpp>

cv::FaceDetectorYN* cveFaceDetectorYNCreate(
cv::String* model,
cv::String* config,
CvSize* inputSize,
float scoreThreshold,
float nmsThreshold,
int topK,
int backendId,
int targetId,
cv::Ptr<cv::FaceDetectorYN>** sharedPtr)
{
#ifdef HAVE_OPENCV_OBJDETECT
cv::Ptr<cv::FaceDetectorYN> ptr = cv::FaceDetectorYN::create(
*model,
*config,
*inputSize,
scoreThreshold,
nmsThreshold,
topK,
backendId,
targetId);
*sharedPtr = new cv::Ptr<cv::FaceDetectorYN>(ptr);
return (*sharedPtr)->get();
#else
throw_no_objdetect();
#endif
}

void cveFaceDetectorYNRelease(cv::Ptr<cv::FaceDetectorYN>** faceDetector)
{
#ifdef HAVE_OPENCV_OBJDETECT
delete* faceDetector;
*faceDetector = 0;
#else
throw_no_objdetect();
#endif
}

int cveFaceDetectorYNDetect(cv::FaceDetectorYN* faceDetector, cv::_InputArray* image, cv::_OutputArray* faces)
{
#ifdef HAVE_OPENCV_OBJDETECT
return faceDetector->detect(*image, *faces);
#else
throw_no_objdetect();
#endif
}
34 changes: 34 additions & 0 deletions src/OpenCvSharpExtern/face_detector_yn.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#ifndef NO_OBJDETECT

// ReSharper disable IdentifierTypo
// ReSharper disable CppInconsistentNaming
// ReSharper disable CppNonInlineFunctionDefinitionInHeaderFile

#include "my_functions.h"
#include <opencv2/core/cvstd.hpp>
#include <opencv2/core/cvstd_wrapper.hpp>
#include <opencv2/core/types_c.h>
#include <opencv2/objdetect/face.hpp>

#ifndef _WINRT_DLL

CVAPI(cv::FaceDetectorYN*) cveFaceDetectorYNCreate(
cv::String* model,
cv::String* config,
CvSize* inputSize,
float scoreThreshold,
float nmsThreshold,
int topK,
int backendId,
int targetId,
cv::Ptr<cv::FaceDetectorYN>** sharedPtr);

CVAPI(void) cveFaceDetectorYNRelease(cv::Ptr<cv::FaceDetectorYN>** faceDetector);

CVAPI(int) cveFaceDetectorYNDetect(cv::FaceDetectorYN* faceDetector, cv::_InputArray* image, cv::_OutputArray* faces);

#endif

#endif // NO_OBJDETECT
Loading