使用虹软人脸识别算法(免费算法)实现摄像头内人脸追踪。
算法初始化
//人脸追踪引擎
IntPtr FTtrackingEngine = IntPtr.Zero;
int WORKBUF_SIZE = 40 * 1024 * 1024;
IntPtr pWorkMem_FT;
//虹软SDK、APPID,KEY,到官方网站申请下载,这里隐藏^o^,https://ai.arcsoft.com.cn/
private static string APPID = "***************************************************************";
private static string FT_SDKKEY = "***************************************************************";
//初始化
pWorkMem_FT = Marshal.AllocHGlobal(WORKBUF_SIZE);
int retCode = ArcsoftFace.AFT_FSDK_InitialFaceEngine(APPID, FT_SDKKEY, pWorkMem_FT, WORKBUF_SIZE, ref FTtrackingEngine, 5, 16, 1);
if (retCode != 0)
{
b_faceengine = false;
MessageBox.Show(string.Format("人脸追踪引擎初始化失败,错误码={0}", retCode), "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
//摄像头线程内调用算法函数实现人脸追踪
private void Play_Camera()
{
while (bPlayflag)
{
Mat cFrame = new Mat();
m_vCapture.Read(cFrame);
int sleepTime = (int)Math.Round(1000 / m_vCapture.Fps);
Cv2.WaitKey(sleepTime);
if (cFrame.Empty())
{
continue;
}
Cv2.Flip(cFrame, cFrame, OpenCvSharp.FlipMode.Y);
int width = 0;
int height = 0;
int pitch = 0;
byte[] imageData = GetBtyeFromPic(cFrame.ToBitmap(), ref width, ref height, ref pitch);
IntPtr imageDataPtr = Marshal.AllocHGlobal(imageData.Length);
Marshal.Copy(imageData, 0, imageDataPtr, imageData.Length);
ASVLOFFSCREEN offInput = new ASVLOFFSCREEN();
offInput.u32PixelArrayFormat = 513;
offInput.ppu8Plane = new IntPtr[4];
offInput.ppu8Plane[0] = imageDataPtr;
offInput.i32Width = width;
offInput.i32Height = height;
offInput.pi32Pitch = new int[4];
offInput.pi32Pitch[0] = pitch;
AFT_FSDK_FACERES faceRes = new AFT_FSDK_FACERES();
IntPtr offInputPtr = Marshal.AllocHGlobal(Marshal.SizeOf(offInput));
Marshal.StructureToPtr(offInput, offInputPtr, false);
IntPtr faceResPtr = Marshal.AllocHGlobal(Marshal.SizeOf(faceRes));
//人脸检测
int detectResult = ArcsoftFace.AFT_FSDK_FaceFeatureDetect(FTtrackingEngine, offInputPtr, ref faceResPtr);
object obj = Marshal.PtrToStructure(faceResPtr, typeof(AFT_FSDK_FACERES));
faceRes = (AFT_FSDK_FACERES)obj;
if (faceRes.nFace > 0)
{
MRECT rect = (MRECT)Marshal.PtrToStructure(faceRes.rcFace, typeof(MRECT));
int orient = faceRes.lfaceOrient;
//扩大人脸框
int Scale = 50;
int r_left = rect.left - Scale > 0 ? rect.left - Scale : rect.left;
int r_top = rect.top - Scale > 0 ? rect.top - Scale : rect.top;
int r_right = rect.right + Scale < width ? rect.right + Scale : rect.right;
int r_bottom = rect.bottom + Scale < height ? rect.bottom + Scale : rect.bottom;
rect.left = r_left;
rect.top = r_top;
rect.right = r_right;
rect.bottom = r_bottom;
Rect cMaxrect = new Rect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);//人脸框
if (bTakePicture) //拍照
{
Mat cHead = new Mat(cFrame, cMaxrect);
Cv2.ImWrite(PicSavePath, cHead);
SetPictureBoxImage(pic_head, cHead.ToBitmap());
cHead.Release();
bTakePicture = false;
}
//绘制人脸框
Scalar color = new Scalar(0, 205, 0);
Cv2.Rectangle(cFrame, cMaxrect, color, 2);
}
SetPictureBoxImage(pic_cam, cFrame.ToBitmap());
//释放
imageData = null;
Marshal.FreeHGlobal(imageDataPtr);
cFrame.Release();
}
}
效果图: