人脸识别尝试

人脸识别尝试

参考材料

[(181条消息) Java实现人脸识别(各项目结构都有案例说明)_高冷小伙的博客-CSDN博客_java实现人脸识别](https://blog.csdn.net/alpha_xia/article/details/121755220?ops_request_misc=&request_id=&biz_id=102&utm_term=java 人脸识别&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-0-121755220.nonecase&spm=1018.2226.3001.4187)

下次SDK

人脸识别核心部分是蚕蛹蓝虹公司免费的SDK

下载地址:

开发者中心 (arcsoft.com.cn)

测试阶段

官方给的程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package samplecode;

import com.arcsoft.face.*;
import com.arcsoft.face.enums.*;
import com.arcsoft.face.toolkit.ImageInfo;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import com.arcsoft.face.toolkit.ImageInfoEx;

import static com.arcsoft.face.toolkit.ImageFactory.getGrayData;
import static com.arcsoft.face.toolkit.ImageFactory.getRGBData;


public class FaceEngineTest {


public static void main(String[] args) {

String appId = "7K7KG9zfBVrtyhgdfdfg";
String sdkKey = "AuyJsdgsdfhsf"


FaceEngine faceEngine = new FaceEngine("D:\\AreFace\\libs\\WIN64");
//激活引擎,只需要一次
int errorCode = faceEngine.activeOnline(appId, sdkKey);

if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
System.out.println("引擎激活失败");
}


ActiveFileInfo activeFileInfo=new ActiveFileInfo();
errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
System.out.println("获取激活文件信息失败");
}

//引擎配置,保存默认即可
EngineConfiguration engineConfiguration = new EngineConfiguration();
engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
engineConfiguration.setDetectFaceMaxNum(10);
engineConfiguration.setDetectFaceScaleVal(16);
//功能配置,可以设置面容识别时是否分析年龄、性别、3d等。
FunctionConfiguration functionConfiguration = new FunctionConfiguration();
functionConfiguration.setSupportAge(true);
functionConfiguration.setSupportFace3dAngle(true);
functionConfiguration.setSupportFaceDetect(true);
functionConfiguration.setSupportFaceRecognition(true);
functionConfiguration.setSupportGender(true);
functionConfiguration.setSupportLiveness(true);
functionConfiguration.setSupportIRLiveness(true);
engineConfiguration.setFunctionConfiguration(functionConfiguration);


//初始化引擎
errorCode = faceEngine.init(engineConfiguration);

if (errorCode != ErrorInfo.MOK.getValue()) {
System.out.println("初始化引擎失败");
}


//人脸检测
ImageInfo imageInfo = getRGBData(new File("d:\\aaa.jpg"));
List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
System.out.println(faceInfoList);

//特征提取
FaceFeature faceFeature = new FaceFeature();
errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature);
System.out.println("特征值大小:" + faceFeature.getFeatureData().length);

//人脸检测2
ImageInfo imageInfo2 = getRGBData(new File("d:\\ccc.jpg"));
List<FaceInfo> faceInfoList2 = new ArrayList<FaceInfo>();
errorCode = faceEngine.detectFaces(imageInfo2.getImageData(), imageInfo2.getWidth(), imageInfo2.getHeight(),imageInfo.getImageFormat(), faceInfoList2);
System.out.println(faceInfoList);

//特征提取2
FaceFeature faceFeature2 = new FaceFeature();
errorCode = faceEngine.extractFaceFeature(imageInfo2.getImageData(), imageInfo2.getWidth(), imageInfo2.getHeight(), imageInfo.getImageFormat(), faceInfoList2.get(0), faceFeature2);
System.out.println("特征值大小:" + faceFeature.getFeatureData().length);

//特征比对
FaceFeature targetFaceFeature = new FaceFeature();
targetFaceFeature.setFeatureData(faceFeature.getFeatureData());
FaceFeature sourceFaceFeature = new FaceFeature();
sourceFaceFeature.setFeatureData(faceFeature2.getFeatureData());
FaceSimilar faceSimilar = new FaceSimilar();

errorCode = faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar);

System.out.println("相似度:" + faceSimilar.getScore());

//设置活体测试
errorCode = faceEngine.setLivenessParam(0.5f, 0.7f);
//人脸属性检测,如果上面功能配置没有的话,这里就不可用
FunctionConfiguration configuration = new FunctionConfiguration();
configuration.setSupportAge(true);
configuration.setSupportFace3dAngle(true);
configuration.setSupportGender(true);
configuration.setSupportLiveness(true);
errorCode = faceEngine.process(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList, configuration);


//性别检测,如果上面功能配置没有的话,这里就不可用
List<GenderInfo> genderInfoList = new ArrayList<GenderInfo>();
errorCode = faceEngine.getGender(genderInfoList);
System.out.println("性别:" + genderInfoList.get(0).getGender());

//年龄检测,如果上面功能配置没有的话,这里就不可用
List<AgeInfo> ageInfoList = new ArrayList<AgeInfo>();
errorCode = faceEngine.getAge(ageInfoList);
System.out.println("年龄:" + ageInfoList.get(0).getAge());

//3D信息检测,如果上面功能配置没有的话,这里就不可用
List<Face3DAngle> face3DAngleList = new ArrayList<Face3DAngle>();
errorCode = faceEngine.getFace3DAngle(face3DAngleList);
System.out.println("3D角度:" + face3DAngleList.get(0).getPitch() + "," + face3DAngleList.get(0).getRoll() + "," + face3DAngleList.get(0).getYaw());

//活体检测,如果上面功能配置没有的话,这里就不可用
List<LivenessInfo> livenessInfoList = new ArrayList<LivenessInfo>();
errorCode = faceEngine.getLiveness(livenessInfoList);
System.out.println("活体:" + livenessInfoList.get(0).getLiveness());


//IR属性处理,如果上面功能配置没有的话,这里就不可用
ImageInfo imageInfoGray = getGrayData(new File("d:\\IR_480p.jpg"));
List<FaceInfo> faceInfoListGray = new ArrayList<FaceInfo>();
errorCode = faceEngine.detectFaces(imageInfoGray.getImageData(), imageInfoGray.getWidth(), imageInfoGray.getHeight(), imageInfoGray.getImageFormat(), faceInfoListGray);

FunctionConfiguration configuration2 = new FunctionConfiguration();
configuration2.setSupportIRLiveness(true);
errorCode = faceEngine.processIr(imageInfoGray.getImageData(), imageInfoGray.getWidth(), imageInfoGray.getHeight(), imageInfoGray.getImageFormat(), faceInfoListGray, configuration2);
//IR活体检测,如果上面功能配置没有的话,这里就不可用
List<IrLivenessInfo> irLivenessInfo = new ArrayList<IrLivenessInfo>();
errorCode = faceEngine.getLivenessIr(irLivenessInfo);
System.out.println("IR活体:" + irLivenessInfo.get(0).getLiveness());

ImageInfoEx imageInfoEx = new ImageInfoEx();
imageInfoEx.setHeight(imageInfo.getHeight());
imageInfoEx.setWidth(imageInfo.getWidth());
imageInfoEx.setImageFormat(imageInfo.getImageFormat());
imageInfoEx.setImageDataPlanes(new byte[][]{imageInfo.getImageData()});
imageInfoEx.setImageStrides(new int[]{imageInfo.getWidth() * 3});
List<FaceInfo> faceInfoList1 = new ArrayList<FaceInfo>();
errorCode = faceEngine.detectFaces(imageInfoEx, DetectModel.ASF_DETECT_MODEL_RGB, faceInfoList1);

FunctionConfiguration fun = new FunctionConfiguration();
fun.setSupportAge(true);
errorCode = faceEngine.process(imageInfoEx, faceInfoList1, functionConfiguration);
List<AgeInfo> ageInfoList1 = new ArrayList<AgeInfo>();
int age = faceEngine.getAge(ageInfoList1);
System.out.println("年龄:" + ageInfoList1.get(0).getAge());

FaceFeature feature = new FaceFeature();
errorCode = faceEngine.extractFaceFeature(imageInfoEx, faceInfoList1.get(0), feature);


//引擎卸载
errorCode = faceEngine.unInit();

}
}

注意 这里需要导包 吧需要的包导到maven里边

学习阶段

分析官方给的pdf,来分析又什么用法,学会阅读官方文档也是一种能力

使用步奏第一阶段 配置引擎

获得引擎

==代码中出现的数组都是乱码,具体值需要自己到官网拷贝==

1
2
3
4
5
6
7
8
9
10
11
String appId = "7asdasfG3cxqKmpF1DwijXxJ73s75v7uZqxoT";
String sdkKey = "AuyJJasdqwafgadgBnD5wXzSEPtXs5C";


FaceEngine faceEngine = new FaceEngine("D:\\AreFace\\libs\\WIN64");
//激活引擎,只需要一次
int errorCode = faceEngine.activeOnline(appId, sdkKey);

if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
System.out.println("引擎激活失败");
}

C:\Users\Lenovo\Desktop\人脸识别尝试\libs\WIN64该文件名是从官网拷贝下来的压缩包解压后 xx.dll文件所在的位置

image-20221025162958075

第二步 获得激活文件

激活文件是可以直接new 生成 没有对其的配置

1
2
3
4
5
6
7
8
//创建激活文件
ActiveFileInfo activeFileInfo = new ActiveFileInfo();
errorCode = faceEngine.getActiveFileInfo(activeFileInfo);

//判断激活文件是否获取成功
if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
System.out.println("获取激活文件信息失败");
}

第三步 配置引擎

1
2
3
4
5
6
7
8
9
10
11
//设置配置引擎对象
EngineConfiguration engineConfiguration = new EngineConfiguration();

//几个比较重要的配置设置

//检测模式设置
//这里因为我们是对图片进行人脸识别,因此这里我们使用一个IMAGE模式
engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);

//可检测图片人脸方向设置
engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);//这里我设置的是全方位角设置

具体功能 请参考文档 文档在下载下来的压缩包里有

第四步 配置引擎功能

引擎功能 即引擎能够干什么;

1
2
3
4
5
6
7
8
9
10
11
//功能配置,可以设置面容识别时是否分析年龄、性别、3d等。
FunctionConfiguration functionConfiguration = new FunctionConfiguration();
functionConfiguration.setSupportAge(true);
functionConfiguration.setSupportFace3dAngle(true);
functionConfiguration.setSupportFaceDetect(true);
functionConfiguration.setSupportFaceRecognition(true);
functionConfiguration.setSupportGender(true);
functionConfiguration.setSupportLiveness(true);
functionConfiguration.setSupportIRLiveness(true);

engineConfiguration.setFunctionConfiguration(functionConfiguration);

第五步 初始化引擎

将配置好的引擎和引擎功能的对象都放到引擎里

1
2
3
4
5
6
//初始化引擎 (将配置设置到引擎中)
errorCode = faceEngine.init(engineConfiguration);

if (errorCode!=ErrorInfo.MOK.getValue()){
System.out.println("引擎初始化失败");
}

引擎准备阶段就到此结束,下边就是引擎能进行的操作了

再次强调

1
2
3
4
5
EngineConfiguration engineConfiguration = new EngineConfiguration();
engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
engineConfiguration.setDetectFaceMaxNum(10);
engineConfiguration.setDetectFaceScaleVal(16);

配置引擎时,这里个配置比较重要

从上到下分别是

  • 引擎识别模式,是识别静态图片还是视频流
  • 引擎可以识别的头像角度,这里设置的是都可以识别
  • 引擎识别来拿的最大数量
  • 以及引擎识别等级

使用步奏第二部分 使用引擎

准备图像

人脸特征获取

1
2
3
4
5
6
7
8
9
10
11
//准备文件
File file = new File("D:\\aaa.jpg");

//这里使用detectFaces方法来对图片进行分析 detectFaces需要很多参数 这里使用getRGBData方法来获得这些参数
ImageInfo imageInfo = getRGBData(file);
//分析得到的数据保存在faceInfoList列表中
List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);


System.out.println(faceInfoList);

结果:

1
[com.arcsoft.face.Rect(245, 397 - 937, 1089),1]

如果一个图中有多个人脸也是能够识别的

1
2
3
4
5
6
com.arcsoft.face.Rect(1974, 213 - 2749, 987),1
com.arcsoft.face.Rect(1352, 769 - 1839, 1256),1
com.arcsoft.face.Rect(1112, 550 - 1417, 854),1
com.arcsoft.face.Rect(327, 692 - 571, 936),1
com.arcsoft.face.Rect(950, 249 - 1200, 498),1
com.arcsoft.face.Rect(961, 708 - 1186, 933),1

人脸特征提取

extractFaceFeature方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//人脸特征提取

//在输入一个图片
File file1 = new File("D:\\aaa.jpg");


ImageInfo imageInfo1 = getRGBData(file1);
//分析得到的数据保存在faceInfoList列表中
List<FaceInfo> faceInfoList1 = new ArrayList<FaceInfo>();
faceEngine.detectFaces(imageInfo1.getImageData(), imageInfo1.getWidth(), imageInfo1.getHeight(), imageInfo1.getImageFormat(), faceInfoList1);


for (FaceInfo faceInfo : faceInfoList1) {
System.out.println(faceInfo);
}


//人脸信息都存放在这个对象里
FaceFeature faceFeature = new FaceFeature();
faceEngine.extractFaceFeature(imageInfo1.getImageData(),imageInfo1.getWidth(), imageInfo1.getHeight(), imageInfo1.getImageFormat(),faceInfoList1.get(0),faceFeature);

System.out.println("图片AAA.jpg的特征是大小为:"+faceFeature.getFeatureData().length);

人脸相似度对比

准备两张图片,按照上述的方法,获得两个feature 来进行比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

//在输入一个图片
File file1 = new File("D:\\fff.jpg");


ImageInfo imageInfo1 = getRGBData(file1);
//分析得到的数据保存在faceInfoList列表中
List<FaceInfo> faceInfoList1 = new ArrayList<FaceInfo>();
faceEngine.detectFaces(imageInfo1.getImageData(), imageInfo1.getWidth(), imageInfo1.getHeight(), imageInfo1.getImageFormat(), faceInfoList1);


for (FaceInfo faceInfo : faceInfoList1) {
System.out.print("第一张图片获得的数据:");
System.out.println(faceInfo);
}


//人脸信息都存放在这个对象里
FaceFeature faceFeature = new FaceFeature();
faceEngine.extractFaceFeature(imageInfo1.getImageData(),imageInfo1.getWidth(), imageInfo1.getHeight(), imageInfo1.getImageFormat(),faceInfoList1.get(0),faceFeature);

System.out.println("图片fff.jpg的特征值大小为:"+faceFeature.getFeatureData().length);

//第二个图片
File file2 = new File("D:\\eee.jpg");
ImageInfo imageInfo2 = getRGBData(file2);
ArrayList<FaceInfo> faceInfoList2 = new ArrayList<>();
faceEngine.detectFaces(imageInfo2.getImageData(),imageInfo2.getWidth(),imageInfo2.getHeight(),imageInfo2.getImageFormat(),faceInfoList2);

for (FaceInfo faceInfo : faceInfoList2) {
System.out.print("第二张图片获得的数据:");
System.out.println(faceInfo);
}
//获得脸部信息
FaceFeature faceFeature1 = new FaceFeature();
faceEngine.extractFaceFeature(imageInfo2.getImageData(),imageInfo2.getWidth(),imageInfo2.getHeight(),imageInfo2.getImageFormat(),faceInfoList2.get(0),faceFeature1);
System.out.println("图片eee.jpg的特征值大小为:"+faceFeature1.getFeatureData().length);

/*
* @Param faceFeature
* @Param faceFeature1
* */
FaceSimilar faceSimilar = new FaceSimilar();
//进行图片对比
faceEngine.compareFaceFeature(faceFeature,faceFeature1, CompareModel.ID_PHOTO,faceSimilar);
System.out.println("两张图片的相似度为:"+faceSimilar.getScore());

通过两个面部特征对象 调用方法进行比较 最后获得值

获得可以获得的数据

可以获得的数据包括

  • 年龄 getAge
  • 性别 getGender
  • 人脸三维角度信息 getFace#DAngle
  • 是否为活物 getLiveness
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//获得 年龄 性别

faceEngine.process(imageInfo2.getImageData(),imageInfo2.getWidth(),imageInfo2.getHeight(),imageInfo2.getImageFormat(),faceInfoList2,functionConfiguration);


ImageInfoEx infoEx = new ImageInfoEx();
infoEx.setHeight(imageInfo2.getHeight());
infoEx.setWidth(imageInfo2.getWidth());
infoEx.setImageFormat(imageInfo2.getImageFormat());
infoEx.setImageDataPlanes(new byte[][]{imageInfo2.getImageData()});
infoEx.setImageStrides(new int[]{imageInfo2.getWidth() * 3});
List<FaceInfo> faceInfoList3 = new ArrayList<>();
faceEngine.detectFaces(infoEx, DetectModel.ASF_DETECT_MODEL_RGB,faceInfoList3);

//这里又设置了一个引擎功能 不知道为何
FunctionConfiguration configuration = new FunctionConfiguration();
configuration.setSupportAge(true);
configuration.setSupportFace3dAngle(true);
configuration.setSupportGender(true);
configuration.setSupportLiveness(true);

faceEngine.process(infoEx,faceInfoList3,configuration);


ArrayList<AgeInfo> ageInfos = new ArrayList<>();
int age = faceEngine.getAge(ageInfos);
System.out.println("图片eee.jpg中人物的大致年龄为:"+ageInfos.get(0).getAge());

ArrayList<GenderInfo> genderInfos = new ArrayList<>();
faceEngine.getGender(genderInfos);
System.out.println("图片eee.jpg中的人物的性别为:"+genderInfos.get(0).getGender());

中间有一个新建立的FunctionConfiguration()的对象configure,但是我不明白为什么要新建一个 因为之前的程序中已经存在这个对象了,而且设置的配置也是相同的,日后继续学习

总结

使用别人的包,固然是一个快速入门的方法,但是具象性太多,只能获得面部数据,年龄,性别,是否为活物,等等等。

做一个人脸识别功能,是能够实现的,但是无法生成标志着红框框的图片,生产那种高大上的好像在追踪分析的图片。(或许是我自己不会)

学完这个包的使用,增加了自己阅读各种依赖官方文档的能力,人工智能涉足,后续会继续向更深处学习,争取能够手搓出一个程序

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2023 dwx
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信