/// <summary> /// 提取人脸特征 /// </summary> /// <param name="pEngine"></param> /// <param name="image"></param> /// <param name="singleFaceInfo"></param> /// <returns></returns> public static IntPtr ExtractFeatrue(IntPtr pEngine, Image image, out ASF_SingleFaceInfo singleFaceInfo) { if (image == null) { return(ReturnEmptyStruct(out singleFaceInfo)); } if (image.Width > 1536 || image.Height > 1536) { image = ImageUtil.ScaleImage(image, 1536, 1536); } else { image = ImageUtil.ScaleImage(image, image.Width, image.Height); } ImageInfo imageInfo = ImageUtil.ReadBMP(image); if (imageInfo == null) { return(ReturnEmptyStruct(out singleFaceInfo)); } //进行人脸检测 ASF_MultiFaceInfo multiFaceInfo = DetectFace(pEngine, imageInfo); singleFaceInfo = new ASF_SingleFaceInfo(); IntPtr pFaceModel = ExtractFeatrue(pEngine, imageInfo, multiFaceInfo, out singleFaceInfo); MemoryUtil.Free(imageInfo.imgData); imageInfo.imgData = IntPtr.Zero; return(pFaceModel); }
/// <summary> /// 获取图片信息 /// </summary> /// <param name="image">图片</param> /// <returns>成功或失败</returns> public static ImageInfo ReadBMP(Image image) { ImageInfo imageInfo = new ImageInfo(); Image <Bgr, byte> my_Image = null; try { //图像灰度转化 my_Image = new Image <Bgr, byte>(new Bitmap(image)); imageInfo.format = ASF_ImagePixelFormat.ASVL_PAF_RGB24_B8G8R8; imageInfo.width = my_Image.Width; imageInfo.height = my_Image.Height; imageInfo.imgData = MemoryUtil.Malloc(my_Image.Bytes.Length); MemoryUtil.Copy(my_Image.Bytes, 0, imageInfo.imgData, my_Image.Bytes.Length); return(imageInfo); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { if (my_Image != null) { my_Image.Dispose(); } } return(null); }
/// <summary> /// 人脸检测 /// </summary> /// <param name="pEngine">虹软引擎实例</param> /// <param name="image">图像 可以是window系统的图像对象</param> /// <returns></returns> public static ASF_MultiFaceInfo DetectFace(IntPtr pEngine, Image image) { lock (locks) //上锁 { //创建多张人脸的数据结构体 ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); if (image != null) { ImageInfo imageInfo = ImageUtil.ReadBMP(image); if (imageInfo == null) { return(multiFaceInfo); } multiFaceInfo = DetectFace(pEngine, imageInfo); //释放掉图片信息,减少内存占用 MemoryUtil.Free(imageInfo.imgData); imageInfo.imgData = IntPtr.Zero; return(multiFaceInfo); } else { return(multiFaceInfo); } } }
public static ASF_MultiFaceInfo DetectFace(IntPtr pEngine, Image image) { lock (locks) { ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); if (image != null) { if (image == null) { return(multiFaceInfo); } ImageInfo imageInfo = ImageUtil.ReadBMP(image); if (imageInfo == null) { return(multiFaceInfo); } multiFaceInfo = DetectFace(pEngine, imageInfo); MemoryUtil.Free(imageInfo.imgData); return(multiFaceInfo); } else { return(multiFaceInfo); } } }
/// <summary> /// 性别检测 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <param name="multiFaceInfo">人脸检测结果</param> /// <returns>保存性别检测结果结构体</returns> public static ASF_GenderInfo GenderEstimation(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo, out int retCode) { retCode = -1; IntPtr pMultiFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_MultiFaceInfo>()); MemoryUtil.StructureToPtr(multiFaceInfo, pMultiFaceInfo); if (multiFaceInfo.faceNum == 0) { return(new ASF_GenderInfo()); } //人脸信息处理 retCode = ASFFunctions.ASFProcess(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo, FaceEngineMask.ASF_GENDER); if (retCode == 0) { //获取性别信息 IntPtr pGenderInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_GenderInfo>()); retCode = ASFFunctions.ASFGetGender(pEngine, pGenderInfo); Console.WriteLine("Get Gender Result:" + retCode); ASF_GenderInfo genderInfo = MemoryUtil.PtrToStructure <ASF_GenderInfo>(pGenderInfo); //释放内存 MemoryUtil.Free(pMultiFaceInfo); MemoryUtil.Free(pGenderInfo); return(genderInfo); } else { return(new ASF_GenderInfo()); } }
/// <summary> /// 人脸3D角度检测 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <param name="multiFaceInfo">人脸检测结果</param> /// <returns>保存人脸3D角度检测结果结构体</returns> public static ASF_Face3DAngle Face3DAngleDetection(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo, out int retCode) { IntPtr pMultiFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_MultiFaceInfo>()); MemoryUtil.StructureToPtr(multiFaceInfo, pMultiFaceInfo); if (multiFaceInfo.faceNum == 0) { retCode = -1; return(new ASF_Face3DAngle()); } //人脸信息处理 retCode = ASFFunctions.ASFProcess(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo, FaceEngineMask.ASF_FACE3DANGLE); if (retCode == 0) { //获取人脸3D角度 IntPtr pFace3DAngleInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_Face3DAngle>()); retCode = ASFFunctions.ASFGetFace3DAngle(pEngine, pFace3DAngleInfo); Console.WriteLine("Get Face3D Angle Result:" + retCode); ASF_Face3DAngle face3DAngle = MemoryUtil.PtrToStructure <ASF_Face3DAngle>(pFace3DAngleInfo); //释放内存 MemoryUtil.Free(pMultiFaceInfo); MemoryUtil.Free(pFace3DAngleInfo); return(face3DAngle); } else { return(new ASF_Face3DAngle()); } }
/// <summary> /// 年龄检测 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <param name="multiFaceInfo">人脸检测结果</param> /// <returns>年龄检测结构体</returns> public static ASF_AgeInfo AgeEstimation(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo) { IntPtr pMultiFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_MultiFaceInfo>()); MemoryUtil.StructureToPtr(multiFaceInfo, pMultiFaceInfo); if (multiFaceInfo.faceNum == 0) { return(new ASF_AgeInfo()); } //人脸信息处理 int retCode = ASFFunctions.ASFProcess(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo, FaceEngineMask.ASF_AGE); //获取年龄信息 IntPtr pAgeInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_AgeInfo>()); retCode = ASFFunctions.ASFGetAge(pEngine, pAgeInfo); Console.WriteLine("Get Age Result:" + retCode); ASF_AgeInfo ageInfo = MemoryUtil.PtrToStructure <ASF_AgeInfo>(pAgeInfo); //释放内存 MemoryUtil.Free(pMultiFaceInfo); MemoryUtil.Free(pAgeInfo); return(ageInfo); }
public static ASF_MultiFaceInfo DetectFace(IntPtr pEngine, Image image) { lock (locks) { ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); if (image != null) { if (image.Width > 1536 || image.Height > 1536) { image = ImageUtil.ScaleImage(image, 1536, 1536); } else { image = ImageUtil.ScaleImage(image, image.Width, image.Height); } if (image == null) { return(multiFaceInfo); } ImageInfo imageInfo = ImageUtil.ReadBMP(image); if (imageInfo == null) { return(multiFaceInfo); } multiFaceInfo = DetectFace(pEngine, imageInfo); MemoryUtil.Free(imageInfo.imgData); return(multiFaceInfo); } else { return(multiFaceInfo); } } }
/// <summary> /// 提取单人脸特征 /// </summary> /// <param name="pEngine"></param> /// <param name="image"></param> /// <param name="singleFaceInfo"></param> /// <returns></returns> public static ASF_FaceFeature ExtractFeature(IntPtr pEngine, Image image, ASF_SingleFaceInfo singleFaceInfo) { ImageInfo imageInfo = ImageUtil.ReadBMP(image); if (imageInfo == null) { return(ReturnEmptyFeature()); } IntPtr pSingleFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_SingleFaceInfo>()); MemoryUtil.StructureToPtr(singleFaceInfo, pSingleFaceInfo); IntPtr pFaceFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); int retCode = -1; try { retCode = ASFFunctions.ASFFaceFeatureExtract(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pSingleFaceInfo, pFaceFeature); } catch (Exception e) { Console.WriteLine(e.Message); } if (retCode != 0) { MemoryUtil.Free(pSingleFaceInfo); MemoryUtil.Free(pFaceFeature); MemoryUtil.Free(imageInfo.imgData); pSingleFaceInfo = IntPtr.Zero; pFaceFeature = IntPtr.Zero; imageInfo.imgData = IntPtr.Zero; return(ReturnEmptyFeature()); } //人脸特征feature过滤 ASF_FaceFeature faceFeature = MemoryUtil.PtrToStructure <ASF_FaceFeature>(pFaceFeature); byte[] feature = new byte[faceFeature.featureSize]; MemoryUtil.Copy(faceFeature.feature, feature, 0, faceFeature.featureSize); ASF_FaceFeature localFeature = new ASF_FaceFeature(); localFeature.feature = MemoryUtil.Malloc(feature.Length); MemoryUtil.Copy(feature, 0, localFeature.feature, feature.Length); localFeature.featureSize = feature.Length; //释放指针 MemoryUtil.Free(pSingleFaceInfo); MemoryUtil.Free(pFaceFeature); MemoryUtil.Free(imageInfo.imgData); pSingleFaceInfo = IntPtr.Zero; imageInfo.imgData = IntPtr.Zero; return(localFeature); }
/// <summary> /// 获取多个人脸检测结果中面积最大的人脸 /// </summary> /// <param name="multiFaceInfo">人脸检测结果</param> /// <returns>面积最大的人脸信息</returns> public static ASF_SingleFaceInfo GetMaxFace(ASF_MultiFaceInfo multiFaceInfo) { ASF_SingleFaceInfo singleFaceInfo = new ASF_SingleFaceInfo(); singleFaceInfo.faceRect = new MRECT(); singleFaceInfo.faceOrient = 1; int maxArea = 0; int index = -1; for (int i = 0; i < multiFaceInfo.faceNum; i++) { MRECT rect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects + MemoryUtil.SizeOf <MRECT>() * i); int area = (rect.right - rect.left) * (rect.bottom - rect.top); if (maxArea <= area) { maxArea = area; index = i; } } if (index != -1) { singleFaceInfo.faceRect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects + MemoryUtil.SizeOf <MRECT>() * index); singleFaceInfo.faceOrient = MemoryUtil.PtrToStructure <int>(multiFaceInfo.faceOrients + MemoryUtil.SizeOf <int>() * index); } return(singleFaceInfo); }
/// <summary> /// 获取图片信息 /// </summary> /// <param name="image">图片</param> /// <returns>成功或失败</returns> public static ImageInfo ReadBMP(Image image) { ImageInfo imageInfo = new ImageInfo(); //将Image转换为Format24bppRgb格式的BMP Bitmap bm = new Bitmap(image); BitmapData data = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); try { //位图中第一个像素数据的地址。它也可以看成是位图中的第一个扫描行 IntPtr ptr = data.Scan0; //定义数组长度 int soureBitArrayLength = data.Height * Math.Abs(data.Stride); byte[] sourceBitArray = new byte[soureBitArrayLength]; //将bitmap中的内容拷贝到ptr_bgr数组中 MemoryUtil.Copy(ptr, sourceBitArray, 0, soureBitArrayLength); //填充引用对象字段值 imageInfo.width = data.Width; imageInfo.height = data.Height; imageInfo.format = ASF_ImagePixelFormat.ASVL_PAF_RGB24_B8G8R8; //获取去除对齐位后度图像数据 int line = imageInfo.width * 3; int pitch = Math.Abs(data.Stride); int bgr_len = line * imageInfo.height; byte[] destBitArray = new byte[bgr_len]; /* * 图片像素数据在内存中是按行存储,一般图像库都会有一个内存对齐,在每行像素的末尾位置 * 每行的对齐位会使每行多出一个像素空间(三通道如RGB会多出3个字节,四通道RGBA会多出4个字节) * 以下循环目的是去除每行末尾的对齐位,将有效的像素拷贝到新的数组 */ for (int i = 0; i < imageInfo.height; ++i) { Array.Copy(sourceBitArray, i * pitch, destBitArray, i * line, line); } imageInfo.imgData = MemoryUtil.Malloc(destBitArray.Length); MemoryUtil.Copy(destBitArray, 0, imageInfo.imgData, destBitArray.Length); return(imageInfo); } catch (Exception e) { Console.WriteLine(e.Message); } finally { bm.UnlockBits(data); bm.Dispose(); } return(null); }
/// <summary> /// 人脸检测(PS:检测RGB图像的人脸时,必须保证图像的宽度能被4整除,否则会失败) /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <returns>人脸检测结果</returns> public static ASF_MultiFaceInfo DetectFace(IntPtr pEngine, ImageInfo imageInfo) { ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); IntPtr pMultiFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_MultiFaceInfo>()); int retCode = ASFFunctions.ASFDetectFaces(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo); multiFaceInfo = MemoryUtil.PtrToStructure <ASF_MultiFaceInfo>(pMultiFaceInfo); return(multiFaceInfo); }
private static IntPtr ReturnEmptyStruct(out ASF_SingleFaceInfo singleFaceInfo) { singleFaceInfo = new ASF_SingleFaceInfo(); ASF_FaceFeature emptyFeatrue = new ASF_FaceFeature(); IntPtr pEmptyFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); MemoryUtil.StructureToPtr(emptyFeatrue, pEmptyFeature); return(pEmptyFeature); }
/// <summary> /// 提取人脸特征 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="image">图像</param> /// <returns>保存人脸特征结构体指针</returns> public static IntPtr ExtractFeature(IntPtr pEngine, Image image, out ASF_SingleFaceInfo singleFaceInfo) { image = ImageUtil.ScaleImage(image, image.Width, image.Height); ImageInfo imageInfo = ImageUtil.ReadBMP(image); ASF_MultiFaceInfo multiFaceInfo = DetectFace(pEngine, imageInfo); singleFaceInfo = new ASF_SingleFaceInfo(); IntPtr pFaceModel = ExtractFeature(pEngine, imageInfo, multiFaceInfo, out singleFaceInfo); MemoryUtil.Free(imageInfo.imgData); return(pFaceModel); }
/// <summary> /// 提取人脸特征 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <param name="multiFaceInfo">人脸检测结果</param> /// <returns>保存人脸特征结构体指针</returns> public static IntPtr ExtractFeature(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo, out ASF_SingleFaceInfo singleFaceInfo) { singleFaceInfo = new ASF_SingleFaceInfo(); if (multiFaceInfo.faceRects == null) { ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); IntPtr pEmptyFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); MemoryUtil.StructureToPtr(emptyFeature, pEmptyFeature); return(pEmptyFeature); } singleFaceInfo.faceRect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects); singleFaceInfo.faceOrient = MemoryUtil.PtrToStructure <int>(multiFaceInfo.faceOrients); IntPtr pSingleFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_SingleFaceInfo>()); MemoryUtil.StructureToPtr(singleFaceInfo, pSingleFaceInfo); IntPtr pFaceFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); int retCode = ASFFunctions.ASFFaceFeatureExtract(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pSingleFaceInfo, pFaceFeature); Console.WriteLine("FR Extract Feature result:" + retCode); if (retCode != 0) { //释放指针 MemoryUtil.Free(pSingleFaceInfo); MemoryUtil.Free(pFaceFeature); ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); IntPtr pEmptyFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); MemoryUtil.StructureToPtr(emptyFeature, pEmptyFeature); return(pEmptyFeature); } //人脸特征feature过滤 ASF_FaceFeature faceFeature = MemoryUtil.PtrToStructure <ASF_FaceFeature>(pFaceFeature); byte[] feature = new byte[faceFeature.featureSize]; MemoryUtil.Copy(faceFeature.feature, feature, 0, faceFeature.featureSize); ASF_FaceFeature localFeature = new ASF_FaceFeature(); localFeature.feature = MemoryUtil.Malloc(feature.Length); MemoryUtil.Copy(feature, 0, localFeature.feature, feature.Length); localFeature.featureSize = feature.Length; IntPtr pLocalFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); MemoryUtil.StructureToPtr(localFeature, pLocalFeature); //释放指针 MemoryUtil.Free(pSingleFaceInfo); MemoryUtil.Free(pFaceFeature); return(pLocalFeature); }
/// <summary> /// 获取图片IR信息 /// </summary> /// <param name="image">图片</param> /// <returns>成功或失败</returns> public static ImageInfo ReadBMP_IR(Bitmap image) { ImageInfo imageInfo = new ImageInfo(); BitmapData data = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); try { //位图中第一个像素数据的地址。它也可以看成是位图中的第一个扫描行 IntPtr ptr = data.Scan0; //定义数组长度 int soureBitArrayLength = data.Height * Math.Abs(data.Stride); byte[] sourceBitArray = new byte[soureBitArrayLength]; //将bitmap中的内容拷贝到ptr_bgr数组中 MemoryUtil.Copy(ptr, sourceBitArray, 0, soureBitArrayLength); //填充引用对象字段值 imageInfo.width = data.Width; imageInfo.height = data.Height; imageInfo.format = (int)ASF_ImagePixelFormat.ASVL_PAF_GRAY; //获取去除对齐位后度图像数据 int line = imageInfo.width; int pitch = Math.Abs(data.Stride); int ir_len = line * imageInfo.height; byte[] destBitArray = new byte[ir_len]; //灰度化 int j = 0; double colortemp = 0; for (int i = 0; i < sourceBitArray.Length; i += 3) { colortemp = sourceBitArray[i + 2] * 0.299 + sourceBitArray[i + 1] * 0.587 + sourceBitArray[i] * 0.114; destBitArray[j++] = (byte)colortemp; } imageInfo.imgData = MemoryUtil.Malloc(destBitArray.Length); MemoryUtil.Copy(destBitArray, 0, imageInfo.imgData, destBitArray.Length); return(imageInfo); } catch (Exception e) { throw e; } finally { image.UnlockBits(data); } }
/// <summary> /// 获取图片信息 /// </summary> /// <param name="imageUrl">图片文件地址</param> /// <returns>成功返回一个ImageInfo结构, 失败返回null</returns> public static ImageInfo ReadBMP(Image image) { //创建一个ASF的图像信息结构 ImageInfo imageInfo = new ImageInfo(); //创建一个Emgu的图像结构,用于将位图像流进行传唤,传唤为RBG格式的byte数组 Image <Bgr, byte> my_Image = null; //创建一个位图像对象 Bitmap bitmap = null; try { //根据Image流实例化位图像对象 bitmap = new Bitmap(image); if (bitmap == null) { return(null); } //根据位图对象创建 Emgu对象,利用Opencv接口进行格式转换 my_Image = new Image <Bgr, byte>(bitmap); //图像的byte数组格式为[Bule0, Green0, Red0,...,Bule(n-1), Green(n-1), Red(n-1)] imageInfo.format = ASF_ImagePixelFormat.ASVL_PAF_RGB24_B8G8R8; imageInfo.width = my_Image.Width; imageInfo.height = my_Image.Height; imageInfo.imgData = MemoryUtil.Malloc(my_Image.Bytes.Length); MemoryUtil.Copy(my_Image.Bytes, 0, imageInfo.imgData, my_Image.Bytes.Length); return(imageInfo); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { if (my_Image != null) { my_Image.Dispose(); my_Image = null; } if (bitmap != null) { bitmap.Dispose(); bitmap = null; } } return(null); }
/// <summary> /// 单人脸性别检测 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="image">图片</param> /// <param name="singleFaceInfo">单人脸信息</param> /// <returns>性别估计结果</returns> public static ASF_GenderInfo GenderEstimation(IntPtr pEngine, Image image, ASF_SingleFaceInfo singleFaceInfo) { ImageInfo imageInfo = ImageUtil.ReadBMP(image); ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); multiFaceInfo.faceRects = MemoryUtil.Malloc(MemoryUtil.SizeOf <MRECT>()); MemoryUtil.StructureToPtr <MRECT>(singleFaceInfo.faceRect, multiFaceInfo.faceRects); multiFaceInfo.faceOrients = MemoryUtil.Malloc(MemoryUtil.SizeOf <int>()); MemoryUtil.StructureToPtr <int>(singleFaceInfo.faceOrient, multiFaceInfo.faceOrients); multiFaceInfo.faceNum = 1; ASF_GenderInfo genderInfo = GenderEstimation(pEngine, imageInfo, multiFaceInfo); MemoryUtil.Free(imageInfo.imgData); return(genderInfo); }
/// <summary> /// 红外活体检测 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <param name="multiFaceInfo">活体检测结果</param> /// <returns>保存活体检测结果结构体</returns> public static ASF_LivenessInfo LivenessInfo_IR(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo, out int retCode) { IntPtr pMultiFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_MultiFaceInfo>()); MemoryUtil.StructureToPtr(multiFaceInfo, pMultiFaceInfo); if (multiFaceInfo.faceNum == 0) { retCode = -1; //释放内存 MemoryUtil.Free(pMultiFaceInfo); return(new ASF_LivenessInfo()); } try { //人脸信息处理 retCode = ASFFunctions.ASFProcess_IR(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo, FaceEngineMask.ASF_IR_LIVENESS); if (retCode == 0) { //获取活体检测结果 IntPtr pLivenessInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_LivenessInfo>()); retCode = ASFFunctions.ASFGetLivenessScore_IR(pEngine, pLivenessInfo); Console.WriteLine("Get Liveness Result:" + retCode); ASF_LivenessInfo livenessInfo = MemoryUtil.PtrToStructure <ASF_LivenessInfo>(pLivenessInfo); //释放内存 MemoryUtil.Free(pMultiFaceInfo); MemoryUtil.Free(pLivenessInfo); return(livenessInfo); } else { //释放内存 MemoryUtil.Free(pMultiFaceInfo); return(new ASF_LivenessInfo()); } } catch { retCode = -1; //释放内存 MemoryUtil.Free(pMultiFaceInfo); return(new ASF_LivenessInfo()); } }
/// <summary> /// 获取图片信息 /// </summary> /// <param name="image">图片</param> /// <returns>成功或失败</returns> public static ImageInfo ReadBMP(Image image) { ImageInfo imageInfo = new ImageInfo(); //将Image转换为Format24bppRgb格式的BMP Bitmap bm = new Bitmap(image); BitmapData data = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); try { //位图中第一个像素数据的地址。它也可以看成是位图中的第一个扫描行 IntPtr ptr = data.Scan0; //定义数组长度 int soureBitArrayLength = data.Height * Math.Abs(data.Stride); byte[] sourceBitArray = new byte[soureBitArrayLength]; //将bitmap中的内容拷贝到ptr_bgr数组中 MemoryUtil.Copy(ptr, sourceBitArray, 0, soureBitArrayLength); //填充引用对象字段值 imageInfo.width = data.Width; imageInfo.height = data.Height; imageInfo.format = (int)ASF_ImagePixelFormat.ASVL_PAF_RGB24_B8G8R8; imageInfo.imgData = MemoryUtil.Malloc(sourceBitArray.Length); MemoryUtil.Copy(sourceBitArray, 0, imageInfo.imgData, sourceBitArray.Length); return(imageInfo); } catch (Exception e) { throw e; } finally { bm.UnlockBits(data); bm.Dispose(); } }
/// <summary> /// 人脸检测 /// 检测RGB图像的人脸时,必须保证图像的宽度能被4整除,否则会失败 /// </summary> /// <param name="pEngine">引擎</param> /// <param name="imageInfo">图像数据</param> /// <returns></returns> public static ASF_MultiFaceInfo DetectFace(IntPtr pEngine, ImageInfo imageInfo) { //创建多张人脸的数据结构体 ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); //创建一个指针可以指向MultiFaceInfo结构 IntPtr pMultiFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_MultiFaceInfo>()); int retCode = ASFFunctions.ASFDetectFaces(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo); //当人脸识别错误,则释放内存,返回一个默认的结构 if (retCode != 0) { MemoryUtil.Free(pMultiFaceInfo); pMultiFaceInfo = IntPtr.Zero; return(multiFaceInfo); } //将从C++程序集得到的多人脸结构内存转义成C#的多人脸结构体中 multiFaceInfo = MemoryUtil.PtrToStructure <ASF_MultiFaceInfo>(pMultiFaceInfo); MemoryUtil.Free(pMultiFaceInfo); pMultiFaceInfo = IntPtr.Zero; return(multiFaceInfo); }
/// <summary> /// 获取图片IR信息 /// </summary> /// <param name="image">图片</param> /// <returns>成功或失败</returns> public static ImageInfo ReadBMP_IR(Bitmap bitmap) { ImageInfo imageInfo = new ImageInfo(); Image <Bgr, byte> my_Image = null; Image <Gray, byte> gray_image = null; try { //图像灰度转化 my_Image = new Image <Bgr, byte>(bitmap); gray_image = my_Image.Convert <Gray, byte>(); //灰度化函数 imageInfo.format = ASF_ImagePixelFormat.ASVL_PAF_GRAY; imageInfo.width = gray_image.Width; imageInfo.height = gray_image.Height; imageInfo.imgData = MemoryUtil.Malloc(gray_image.Bytes.Length); MemoryUtil.Copy(gray_image.Bytes, 0, imageInfo.imgData, gray_image.Bytes.Length); return(imageInfo); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { if (my_Image != null) { my_Image.Dispose(); } if (gray_image != null) { gray_image.Dispose(); } } return(null); }
/// <summary> /// 提取人脸特征 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="image">图像</param> /// <returns>保存人脸特征结构体指针</returns> public static IntPtr ExtractFeature(IntPtr pEngine, Image image, out ASF_SingleFaceInfo singleFaceInfo) { if (image.Width > 1536 || image.Height > 1536) { image = ImageUtil.ScaleImage(image, 1536, 1536); } else { image = ImageUtil.ScaleImage(image, image.Width, image.Height); } if (image == null) { singleFaceInfo = new ASF_SingleFaceInfo(); ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); IntPtr pEmptyFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); MemoryUtil.StructureToPtr(emptyFeature, pEmptyFeature); return(pEmptyFeature); } ImageInfo imageInfo = ImageUtil.ReadBMP(image); if (imageInfo == null) { singleFaceInfo = new ASF_SingleFaceInfo(); ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); IntPtr pEmptyFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); MemoryUtil.StructureToPtr(emptyFeature, pEmptyFeature); return(pEmptyFeature); } ASF_MultiFaceInfo multiFaceInfo = DetectFace(pEngine, imageInfo); singleFaceInfo = new ASF_SingleFaceInfo(); IntPtr pFaceModel = ExtractFeature(pEngine, imageInfo, multiFaceInfo, out singleFaceInfo); MemoryUtil.Free(imageInfo.imgData); return(pFaceModel); }
/// <summary> /// 从图像信息中提取人脸特征 /// </summary> /// <param name="pEngine">虹软引擎句柄</param> /// <param name="imageInfo">图像信息</param> /// <param name="multiFaceInfo">人脸检测结果</param> /// <param name="singleFaceInfo">单个人脸的位置</param> /// <returns>保存人脸特征结构体指针</returns> public static IntPtr ExtractFeatrue(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo, out ASF_SingleFaceInfo singleFaceInfo) { singleFaceInfo = new ASF_SingleFaceInfo(); //如果没有检测到人脸 if (multiFaceInfo.faceRects == null) { //创建一个空的特征结构体 ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); IntPtr pEmptyFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); MemoryUtil.StructureToPtr(emptyFeature, pEmptyFeature); return(pEmptyFeature); } singleFaceInfo.faceRect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects); singleFaceInfo.faceOrient = MemoryUtil.PtrToStructure <int>(multiFaceInfo.faceOrients); IntPtr pSingleFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_SingleFaceInfo>()); MemoryUtil.StructureToPtr(singleFaceInfo, pSingleFaceInfo); //创建一个人脸特征结构体指针 IntPtr pFaceFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); //执行特征识别运算 int retCode = ASFFunctions.ASFFaceFeatureExtract(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pSingleFaceInfo, pFaceFeature); Console.WriteLine("FR Extract Feature result: " + retCode); //当执行结果不是成功 if (retCode != 0) { MemoryUtil.Free(pSingleFaceInfo); MemoryUtil.Free(pFaceFeature); pSingleFaceInfo = IntPtr.Zero; pFaceFeature = IntPtr.Zero; ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); IntPtr pEmptyFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); MemoryUtil.StructureToPtr(emptyFeature, pEmptyFeature); return(pEmptyFeature); } #region 人脸特征深度复制 ASF_FaceFeature faceFeature = MemoryUtil.PtrToStructure <ASF_FaceFeature>((pFaceFeature)); byte[] feature = new byte[faceFeature.featureSize]; //将特征值提取出来(类型转换成C#的类型 MemoryUtil.Copy(faceFeature.feature, feature, 0, faceFeature.featureSize); ASF_FaceFeature localFeature = new ASF_FaceFeature(); localFeature.feature = MemoryUtil.Malloc(feature.Length); MemoryUtil.Copy(feature, 0, localFeature.feature, feature.Length); localFeature.featureSize = feature.Length; IntPtr pLocalFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); MemoryUtil.StructureToPtr(localFeature, pLocalFeature); MemoryUtil.Free(pSingleFaceInfo); MemoryUtil.Free(pFaceFeature); pSingleFaceInfo = IntPtr.Zero; pFaceFeature = IntPtr.Zero; #endregion return(pLocalFeature); }