Browse Source

Added FaceRecognizerSF from objdetect module.

pull/703/head
Canming Huang 4 years ago
parent
commit
348180ea71
  1. 3
      Emgu.CV.Cuda/Stream.cs
  2. 14
      Emgu.CV.Extern/CMakeLists.txt
  3. 10
      Emgu.CV.Extern/objdetect/FaceDetectorYN.cpp
  4. 68
      Emgu.CV.Extern/objdetect/FaceRecognizerSF.cpp
  5. 15
      Emgu.CV.Extern/objdetect/objdetect_c.h
  6. 22
      Emgu.CV/Objdetect/FaceDetectorYN.cs
  7. 170
      Emgu.CV/Objdetect/FaceRecognizerSF.cs

3
Emgu.CV.Cuda/Stream.cs

@ -67,7 +67,8 @@ namespace Emgu.CV.Cuda
/// </summary>
protected override void DisposeObject()
{
CudaInvoke.streamRelease(ref _ptr);
if (!IntPtr.Zero.Equals(_ptr))
CudaInvoke.streamRelease(ref _ptr);
}
}

14
Emgu.CV.Extern/CMakeLists.txt

@ -1419,13 +1419,15 @@ ENDIF()
"${CMAKE_CURRENT_SOURCE_DIR}/../Emgu.CV/Objdetect/FaceDetectorYN.g.cs"
"cv::FaceDetectorYN"
"FaceDetectorYN"
"ScoreThreshold;NMSThreshold"
"float;float"
"propW;propW"
"ScoreThreshold;NMSThreshold"
"float;float"
"ScoreThreshold;NMSThreshold;TopK;InputSize"
"float;float;int;CvSize"
"propW;propW;propW;struct"
"ScoreThreshold;NMSThreshold;TopK;InputSize"
"float;float;int;System.Drawing.Size"
"The score threshold to filter out bounding boxes of score less than the given value;
The Non-maximum-suppression threshold to suppress bounding boxes that have IoU greater than the given value"
The Non-maximum-suppression threshold to suppress bounding boxes that have IoU greater than the given value;
The number of bounding boxes to preserve from top rank based on score;
The size for the network input, which overwrites the input size of creating model."
"Emgu.CV"
"CvInvoke"
"FaceDetectorYN"

10
Emgu.CV.Extern/objdetect/FaceDetectorYN.cpp

@ -33,18 +33,22 @@ cv::FaceDetectorYN* cveFaceDetectorYNCreate(
throw_no_objdetect();
#endif
}
void cveFaceDetectorYNRelease(cv::Ptr<cv::FaceDetectorYN>** faceDetetor)
void cveFaceDetectorYNRelease(cv::Ptr<cv::FaceDetectorYN>** faceDetector)
{
#ifdef HAVE_OPENCV_OBJDETECT
delete* faceDetetor;
*faceDetetor = 0;
delete* faceDetector;
*faceDetector = 0;
#else
throw_no_objdetect();
#endif
}
int cveFaceDetectorYNDetect(cv::FaceDetectorYN* faceDetetor, cv::_InputArray* image, cv::_OutputArray* faces)
{
#ifdef HAVE_OPENCV_OBJDETECT
return faceDetetor->detect(*image, *faces);
#else
throw_no_objdetect();
#endif
}

68
Emgu.CV.Extern/objdetect/FaceRecognizerSF.cpp

@ -0,0 +1,68 @@
//----------------------------------------------------------------------------
//
// Copyright (C) 2004-2021 by EMGU Corporation. All rights reserved.
//
//----------------------------------------------------------------------------
#include "objdetect_c.h"
cv::FaceRecognizerSF* cveFaceRecognizerSFCreate(
cv::String* model,
cv::String* config,
int backendId,
int targetId,
cv::Ptr<cv::FaceRecognizerSF>** sharedPtr)
{
#ifdef HAVE_OPENCV_OBJDETECT
cv::Ptr<cv::FaceRecognizerSF> ptr = cv::FaceRecognizerSF::create(
*model,
*config,
backendId,
targetId);
*sharedPtr = new cv::Ptr<cv::FaceRecognizerSF>(ptr);
return (*sharedPtr)->get();
#else
throw_no_objdetect();
#endif
}
void cveFaceRecognizerSFRelease(cv::Ptr<cv::FaceRecognizerSF>** faceRecognizer)
{
#ifdef HAVE_OPENCV_OBJDETECT
delete* faceRecognizer;
*faceRecognizer = 0;
#else
throw_no_objdetect();
#endif
}
void cveFaceRecognizerSFAlignCrop(cv::FaceRecognizerSF* faceRecognizer, cv::_InputArray* srcImg, cv::_InputArray* faceBox, cv::_OutputArray* alignedImg)
{
#ifdef HAVE_OPENCV_OBJDETECT
faceRecognizer->alignCrop(*srcImg, *faceBox, *alignedImg);
#else
throw_no_objdetect();
#endif
}
void cveFaceRecognizerSFFeature(cv::FaceRecognizerSF* faceRecognizer, cv::_InputArray* alignedImg, cv::_OutputArray* faceFeature)
{
#ifdef HAVE_OPENCV_OBJDETECT
faceRecognizer->feature(*alignedImg, *faceFeature);
#else
throw_no_objdetect();
#endif
}
double cveFaceRecognizerSFMatch(cv::FaceRecognizerSF* faceRecognizer, cv::_InputArray* faceFeature1, cv::_InputArray* faceFeature2, int disType)
{
#ifdef HAVE_OPENCV_OBJDETECT
return faceRecognizer->match(*faceFeature1, *faceFeature2, disType);
#else
throw_no_objdetect();
#endif
}

15
Emgu.CV.Extern/objdetect/objdetect_c.h

@ -127,6 +127,17 @@ CVAPI(cv::FaceDetectorYN*) cveFaceDetectorYNCreate(
int targetId,
cv::Ptr<cv::FaceDetectorYN>** sharedPtr);
CVAPI(void) cveFaceDetectorYNRelease(cv::Ptr<cv::FaceDetectorYN>** faceDetector);
CVAPI(int) cveFaceDetectorYNDetect(cv::FaceDetectorYN* faceDetetor, cv::_InputArray* image, cv::_OutputArray* faces);
CVAPI(int) cveFaceDetectorYNDetect(cv::FaceDetectorYN* faceDetector, cv::_InputArray* image, cv::_OutputArray* faces);
CVAPI(cv::FaceRecognizerSF*) cveFaceRecognizerSFCreate(
cv::String* model,
cv::String* config,
int backendId,
int targetId,
cv::Ptr<cv::FaceRecognizerSF>** sharedPtr);
CVAPI(void) cveFaceRecognizerSFRelease(cv::Ptr<cv::FaceRecognizerSF>** faceRecognizer);
CVAPI(void) cveFaceRecognizerSFAlignCrop(cv::FaceRecognizerSF* faceRecognizer, cv::_InputArray* srcImg, cv::_InputArray* faceBox, cv::_OutputArray* alignedImg);
CVAPI(void) cveFaceRecognizerSFFeature(cv::FaceRecognizerSF* faceRecognizer, cv::_InputArray* alignedImg, cv::_OutputArray* faceFeature);
CVAPI(double) cveFaceRecognizerSFMatch(cv::FaceRecognizerSF* faceRecognizer, cv::_InputArray* faceFeature1, cv::_InputArray* faceFeature2, int disType);
#endif

22
Emgu.CV/Objdetect/FaceDetectorYN.cs

@ -13,10 +13,22 @@ using Emgu.Util;
namespace Emgu.CV
{
/// <summary>
/// DNN-based face detector
/// </summary>
public partial class FaceDetectorYN : SharedPtrObject
{
/// <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 compability, 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,
@ -44,6 +56,12 @@ namespace Emgu.CV
}
}
/// <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(IInputArray image, IOutputArray faces)
{
using (InputArray iaImage = image.GetInputArray())

170
Emgu.CV/Objdetect/FaceRecognizerSF.cs

@ -0,0 +1,170 @@
//----------------------------------------------------------------------------
// Copyright (C) 2004-2021 by EMGU Corporation. All rights reserved.
//----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using Emgu.Util;
namespace Emgu.CV
{
/// <summary>
/// DNN-based face recognizer
/// </summary>
public partial class FaceRecognizerSF : SharedPtrObject
{
/// <summary>
/// Definition of distance used for calculating the distance between two face features
/// </summary>
public enum DisType
{
/// <summary>
/// Cosine distance
/// </summary>
Cosine = 0,
/// <summary>
/// Norm L2
/// </summary>
NormL2 = 1
};
/// <summary>
/// Creates an instance of this class with given parameters.
/// </summary>
/// <param name="model">The path of the onnx model used for face recognition</param>
/// <param name="config">The path to the config file for compability, which is not requested for ONNX models</param>
/// <param name="backendId">The id of backend</param>
/// <param name="targetId">The id of target device</param>
public FaceRecognizerSF(
String model,
String config,
Emgu.CV.Dnn.Backend backendId,
Emgu.CV.Dnn.Target targetId)
{
using (CvString csModel = new CvString(model))
using (CvString csConfig = new CvString(config))
{
_ptr = CvInvoke.cveFaceRecognizerSFCreate(
csModel,
csConfig,
backendId,
targetId,
ref _sharedPtr
);
}
}
/// <summary>
/// Aligning image to put face on the standard position.
/// </summary>
/// <param name="srcImg">Input image</param>
/// <param name="faceBox">The detection result used for indicate face in input image</param>
/// <param name="alignedImg">Output aligned image</param>
public void AlignCrop(
IInputArray srcImg,
IInputArray faceBox,
IOutputArray alignedImg)
{
using (InputArray iaSrcImg = srcImg.GetInputArray())
using (InputArray iaFaceBox = faceBox.GetInputArray())
using (OutputArray oaAlignedImg = alignedImg.GetOutputArray())
{
CvInvoke.cveFaceRecognizerSFAlignCrop(_ptr, iaSrcImg, iaFaceBox, oaAlignedImg);
}
}
/// <summary>
/// Extracting face feature from aligned image.
/// </summary>
/// <param name="alignedImg">Input aligned image</param>
/// <param name="faceFeature">Output face feature</param>
public void Feature(IInputArray alignedImg, IOutputArray faceFeature)
{
using (InputArray iaAlignedImg = alignedImg.GetInputArray())
using (OutputArray oaFaceFeature = faceFeature.GetOutputArray())
{
CvInvoke.cveFaceRecognizerSFFeature(_ptr, iaAlignedImg, oaFaceFeature);
}
}
/// <summary>
/// Calculating the distance between two face features.
/// </summary>
/// <param name="faceFeature1">The first input feature</param>
/// <param name="faceFeature2">The second input feature of the same size and the same type as <paramref name="faceFeature1"/></param>
/// <param name="disType">Defining the similarity with optional values</param>
/// <returns>The distance between two face features.</returns>
public double Match(
IInputArray faceFeature1,
IInputArray faceFeature2,
DisType disType = DisType.Cosine)
{
using (InputArray iaFaceFeature1 = faceFeature1.GetInputArray())
using (InputArray iaFaceFeature2 = faceFeature2.GetInputArray())
{
return CvInvoke.cveFaceRecognizerSFMatch(
_ptr,
iaFaceFeature1,
iaFaceFeature2,
disType
);
}
}
/// <summary>
/// Release the unmanaged memory associated with this FaceRecognizerSF
/// </summary>
protected override void DisposeObject()
{
if (!IntPtr.Zero.Equals(_sharedPtr))
{
CvInvoke.cveFaceRecognizerSFRelease(ref _sharedPtr);
_ptr = IntPtr.Zero;
}
}
}
public static partial class CvInvoke
{
[DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)]
internal static extern IntPtr cveFaceRecognizerSFCreate(
IntPtr model,
IntPtr config,
Emgu.CV.Dnn.Backend backendId,
Emgu.CV.Dnn.Target targetId,
ref IntPtr sharedPtr);
[DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)]
internal static extern void cveFaceRecognizerSFRelease(ref IntPtr faceRecognizer);
[DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)]
internal static extern void cveFaceRecognizerSFAlignCrop(
IntPtr faceRecognizer,
IntPtr srcImg,
IntPtr faceBox,
IntPtr alignedImg);
[DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)]
internal static extern void cveFaceRecognizerSFFeature(
IntPtr faceRecognizer,
IntPtr alignedImg,
IntPtr faceFeature);
[DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)]
internal static extern double cveFaceRecognizerSFMatch(
IntPtr faceRecognizer,
IntPtr faceFeature1,
IntPtr faceFeature2,
FaceRecognizerSF.DisType disType);
}
}
Loading…
Cancel
Save