Android的虹软人脸识别和活体检测(附含10000个人脸图片和特征zip下载)
文章目录
1.获取app_id和sdk_key和下载SDK的步骤
获取app_id
和sdk_key
的网址:
https://ai.arcsoft.com.cn/ucenter/resource/build/index.html#/addFreesdk/1002?from=index
第一步骤:先打开这网址再填写信息如下:
第二步骤:填写好了点击“创建新应用”后显示添加应用框如下:
第三步骤:填写好了点击“立即创建”,再点击“确认”,直接获取app_id
和sdk_key
和下载sdk
https://ai.arcsoft.com.cn/ucenter/resource/build/index.html#/application/204190
FaceSearchResultAdapter.java
中新增代码
又报错:
Glide.with(holder.imageView)
改为:
Glide.with(holder.imageView.getContext())
2.填写app_id和sdk_key
Constants.java
中
public static final String APP_ID = "官网获取的APP_ID";
public static final String SDK_KEY = "官网获取的SDK_KEY";
4.翻译
SDK:软件开发包
Arcface:人脸识别
soft:软的
sample:样品
regist:注册
register:注册
AFR:arcsoft(虹软) face(脸) recognition(识别)
FSDK:这只是一个命名,重要的只是FR
AFD: arcsoft(虹软) face(脸) detection(检测)
Engine:引擎
Version:版本
result:结果
Feature:特征
score:分数
Matching:匹配
Pair:一对
clone:一模一样
AFT:arcsoft(虹软) face(脸) tracking(跟踪)
Handler:处理
Runnable:可运行的
run:运行
Detection:检测
Still:还是
surface:表面
After:后
Render:渲染(一种画法)
Preview:预览
Error:错误
HIGHER : 更高
Creat:创造
Destroy:破坏
join:加入
Callback:回调
Extract:取
Feature:特征
Initial:初始的
Uninitial:未初始化的
Num:号码
Parameters:参数
Frame:框
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
Changed:改变
Later:以后
Regist:注册
index:指数
result:结果
params:参数
YUV 表示三个分量, Y 表示 亮度(Luminance),即灰度值,UV表示色度
what: 什么
reg:注册
EVENT:事件
obtain:获取
Empty:空
loop:循环
Ratio : 比
Supported:支持
Application:应用
Permission:权限
Info:信息
over:结束
Canvas:画布
Paint:画
sleep : 休眠
part:一部分
reset:重新
body:身体
recognize:认出
jump:跳
choose:选择
function:功能
manage:管理
down:向下
number:数
suffix:后缀
5.人脸识别错误码
成功 = 0,
错误原因不明 = 1,
无效的参数 = 2,
引擎不支持 = 3,
内存不足 = 4,
状态错误 = 5,
用户取消相关操作 = 6,
操作时间过期 = 7,
用户暂停操作 = 8,
缓冲上溢 = 9,
缓冲下溢 = 10,
存贮空间不足 = 11,
组件不存在 = 12,
全局数据不存在 = 13,
无效的AppId = 28673,
无效的SDKKey = 28674,
AppId和SDKKey不匹配 = 28675,
SDKKey和使用的SDK不匹配 = 28676,
系统版本不被当前SDK所支持 = 28677,
SDK有效期过期_需要重新下载更新 = 28678,
无效的输入内存 = 73729,
无效的输入图像参数 = 73730,
无效的脸部信息1 = 73731,
当前设备无GPU可用 = 73732,
待比较的两个人脸特征的版本不一致 = 73733,
人脸特征检测错误未知 = 81921,
人脸特征检测内存错误 = 81922,
人脸特征检测格式错误 = 81923,
人脸特征检测参数错误 = 81924,
人脸特征检测结果置信度低 = 81925,
Engine不支持的检测属性 = 86017,
需要检测的属性未初始化 = 86018,
待获取的属性未在process中处理过 = 86019,
PROCESS不支持的检测属性 = 86020,
无效的输入图像 = 86021,
无效的脸部信息2 = 86022,
SDK激活失败_请打开读写权限 = 90113,
SDK已激活 = 90114,
SDK未激活 = 90115,
detectFaceScaleVal不支持 = 90116,
SDK版本不匹配 = 90117,
设备不匹配 = 90118,
唯一标识不匹配 = 90119,
参数为空 = 90120,
活体检测功能已过期 = 90121,
版本不支持 = 90122,
签名错误 = 90123,
数据库插入错误 = 90124,
唯一标识符校验失败 = 90125,
颜色空间不支持 = 90126,
图片宽度或高度不支持 = 90127,
READ_PHONE_STATE权限被拒绝 = 90128,
激活数据被破坏, 请删除激活文件_重新进行激活 = 90129,
无法解析主机地址 = 94209,
无法连接服务器 = 94210,
网络连接超时 = 94211,
网络未知错误 = 94212,
无法连接激活码服务器 = 98305,
服务器系统错误 = 98306,
请求参数错误 = 98307,
激活码正确_且未被使用_但和传入的APPID及APPKEY不匹配 = 98308,
传入的KEY值虽然正确_但此KEY已经被激活 = 98309,
KEY格式不对_一般来说是KEY错误或者未传入KEY值 = 98310
6.人脸识别界面
7.重要的理解
1.FaceServer.java
......
/**
* 用于预览时注册人脸
*
* @param context 上下文对象
* @param nv21 NV21数据
* @param width NV21宽度
* @param height NV21高度
* @param faceInfo {@link FaceEngine#detectFaces(byte[], int, int, int, List)}获取的人脸信息
* @param name 保存的名字,若为空则使用时间戳
* @return 是否注册成功
*/
public boolean registerNv21(Context context, byte[] nv21, int width, int height, FaceInfo faceInfo, String name) {......}
......
/**
* 用于注册照片人脸
*
* @param context 上下文对象
* @param bgr24 bgr24数据
* @param width bgr24宽度
* @param height bgr24高度
* @param name 保存的名字,若为空则使用时间戳
* @return 是否注册成功
*/
public boolean registerBgr24(Context context, byte[] bgr24, int width, int height, String name) {......}
......
什么是Nv21
NV21 的存储格式是,以4 X 4 图片为例子
占用内存为 4 X 4 X 3 / 2 = 24 个字节
Y Y Y Y
Y Y Y Y
Y Y Y Y
Y Y Y Y
V U V U
V U V U
什么是Bgr24
Bgr24:Bgr24像素格式是一种采用24BPP的sRGB格式。每个颜色通道(蓝色blue, 绿色green, 红色red)各占8BPP(位/像素)。
8.自定义
1.app
的build.gradle
中新增代码:
compile 'com.guo.android_extend:android-extend:1.0.5'
2.FaceServer.java
中新增代码:
......
public static List<FaceImgRegisterInfo> faceImgRegisterInfoList;
......
//特征
private static List<FaceRegisterInfo> MyfaceFeatureRegisterInfoList;
//导入手机里的10000个人脸图片
public static List<FaceImgRegisterInfo> MyimportFaceImgRegisterInfo;
//导入手机里的10000个特征
public static List<FaceRegisterInfo> MyimportFaceFeatureRegisterInfo;
......
//获取图片和姓名的信息
public int getImgAndName(Context context){
synchronized (this){
if (ROOT_PATH == null) {
ROOT_PATH = context.getFilesDir().getAbsolutePath();
}
File imgDir = new File(ROOT_PATH + File.separator + SAVE_IMG_DIR);
if (!imgDir.exists() || !imgDir.isDirectory()) {
return 0;
}
File[] imgFiles = imgDir.listFiles();
if (imgFiles == null || imgFiles.length == 0) {
return 0;
}
faceImgRegisterInfoList = new ArrayList<>();
for (File imgFile : imgFiles) {
faceImgRegisterInfoList.add(new FaceImgRegisterInfo(imgFile.getPath(), getName(imgFile.getName())));
}
return faceImgRegisterInfoList.size();
}
}
private String getName(String path){
int start= path.lastIndexOf(":");
int end = path.lastIndexOf(".");
return path.substring(start+1,end);
}
3.activity_face_manage.xml
中新增代码:
<com.guo.android_extend.widget.HListView
android:id="@+id/hlistView"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:scrollbars="none"
app:dividerHeight="1dp"
app:listSelector="@android:drawable/list_selector_background"
android:layout_gravity="center_horizontal"/>
<TextView
android:id="@+id/tv_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="30dp"
android:textColor="#000000"/>
4.FaceManageActivity.java
中新增代码:
......
private HListView mHListView;
public RegisterViewAdapter mRegisterViewAdapter;
......
mHListView = (HListView) findViewById(R.id.hlistView);
TextView facenum = (TextView) findViewById(R.id.tv_number);
downFile();
mRegisterViewAdapter = new RegisterViewAdapter(FaceManageActivity.this);
mHListView.setAdapter(mRegisterViewAdapter);
......
private void downFile()
{
int faceNum = FaceServer.getInstance().getFaceNumber(this);
if (faceNum == 0) {
showToast(getString(R.string.batch_process_no_face_need_to_delete));
}else {
FaceServer.getInstance().getImgAndName(this);
}
}
......
class Holder {
ExtImageView siv;
TextView tv;
}
class RegisterViewAdapter extends BaseAdapter {
Context mContext;
LayoutInflater mLInflater;
public RegisterViewAdapter(Context c) {
mContext = c;
mLInflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
if (FaceServer.faceImgRegisterInfoList==null){
return 0;
}else {
facenum.setText("注册的人脸数:" + FaceServer.faceImgRegisterInfoList.size() + "个");
return FaceServer.faceImgRegisterInfoList.size();
}
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder = null;
if (convertView != null)
holder = (Holder) convertView.getTag();
else {
convertView = mLInflater.inflate(R.layout.item_sample, null);
holder = new Holder();
holder.siv = (ExtImageView) convertView.findViewById(R.id.imageView1);
holder.tv = (TextView) convertView.findViewById(R.id.textView1);
convertView.setTag(holder);
}
if (!(FaceServer.faceImgRegisterInfoList == null)){
if (!FaceServer.faceImgRegisterInfoList.isEmpty()){
FaceImgRegisterInfo face = FaceServer.faceImgRegisterInfoList.get(position);
holder.tv.setText(face.getName());
String path = face.getImgpath();
holder.siv.setImageBitmap(BitmapFactory.decodeFile(path));
holder.siv.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
convertView.setWillNotDraw(false);
}
}
return convertView;
}
}
......
9.查看手机文件里的10000个图片和特征
1.FaceManageActivity.java
private static final String ROOT_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "arcfacedemo";
可以发现Environment.getExternalStorageDirectory().getAbsolutePath()
,这路经:/storage/emulated/0/
,但是我想知道这路经到底在哪,去百度找了很多都找不到,看来是说无法查看
这路经可以如何改才能查看
怎么改 先看一下
FaceServer.java
,先查看图片
public boolean registerNv21(Context context, byte[] nv21, int width, int height, FaceInfo faceInfo, String name) {
synchronized (this) {
......
if (ROOT_PATH == null) {
ROOT_PATH = context.getFilesDir().getAbsolutePath();
}
......
//图片存储的文件夹
File imgDir = new File(ROOT_PATH + File.separator + SAVE_IMG_DIR);
if (!imgDir.exists() && !imgDir.mkdirs()) {
Log.e(TAG, "registerNv21: can not create image directory");
return false;
}
File file = new File(imgDir + File.separator + userName + IMG_SUFFIX);
// 创建一个头像的Bitmap,存放旋转结果图
Bitmap headBmp = getHeadImage(nv21, width, height, faceInfo.getOrient(), cropRect, ArcSoftImageFormat.NV21);
FileOutputStream fosImage = new FileOutputStream(file);
headBmp.compress(Bitmap.CompressFormat.JPEG, 100, fosImage);
fosImage.close();
......
}
}
改的和FaceServer.java
差不多
String path = Environment.getExternalStorageDirectory().getPath();
//SAVE_IMG_DIR = "register" + File.separator + "imgs";
File MyImgDir = new File(path + File.separator +SAVE_IMG_DIR);
if (!MyImgDir.exists() && !MyImgDir.mkdirs()) {
Log.e(TAG, "已新建文件夹");
return;
}
for (FaceImgRegisterInfo Mypath : faceImgRegisterInfoList){
File file = new File(MyImgDir + File.separator + Mypath.getName());
Bitmap bitmap = BitmapFactory.decodeFile(Mypath.getImgpath());
try {
FileOutputStream fosImage = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fosImage);
fosImage.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
查看手机里的路经/storage/emulated/0/register/imgs/
如下图:
FaceServer.java
中新增代码 就是图片和特征,完整的代码
//把一个隐藏的文件复制到另一个显示的文件(图片和特征)
public void copy() {
synchronized (this) {
String path = Environment.getExternalStorageDirectory().getPath();
//复制到另一个显示的图片文件
File MyImgDir = new File(path + File.separator + SAVE_IMG_DIR);
if (!MyImgDir.exists() && !MyImgDir.mkdirs()) {
Log.e(TAG, "已新建文件夹");
} else {
for (FaceImgRegisterInfo Mypath : faceImgRegisterInfoList) {
File file = new File(MyImgDir + File.separator + Mypath.getName());
Bitmap bitmap = BitmapFactory.decodeFile(Mypath.getImgpath());
try {
FileOutputStream fosImage = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fosImage);
fosImage.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
File featureDir = new File(ROOT_PATH + File.separator + SAVE_FEATURE_DIR);
if (!featureDir.exists() || !featureDir.isDirectory()) {
return;
}
File[] featureFiles = featureDir.listFiles();
if (featureFiles == null || featureFiles.length == 0) {
return;
}
MyfaceFeatureRegisterInfoList = new ArrayList<>();
for (File featureFile : featureFiles) {
try {
FileInputStream fis = new FileInputStream(featureFile);
byte[] feature = new byte[FaceFeature.FEATURE_SIZE];
fis.read(feature);
fis.close();
MyfaceFeatureRegisterInfoList.add(new FaceRegisterInfo(feature, featureFile.getName()));
} catch (IOException e) {
e.printStackTrace();
}
}
//复制到另一个显示的特征文件
File MyfeatureDir = new File(path + File.separator + SAVE_FEATURE_DIR);
if (!MyfeatureDir.exists() && !MyfeatureDir.mkdirs()) {
Log.e(TAG, "已新建文件夹");
return;
}
for (FaceRegisterInfo bytedata : MyfaceFeatureRegisterInfoList) {
File file = new File(MyfeatureDir + File.separator + bytedata.getName());
FileOutputStream fosFeature = null;
try {
fosFeature = new FileOutputStream(file);
fosFeature.write(bytedata.getFeatureData());
fosFeature.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
查看手机里的路经/storage/emulated/0/register/Features/
如下图:
10.如何导入手机里的图片和特征到人脸库里
1.FaceManageActivity.java
中新增代码:
public void BtnImport(View view){
FaceServer.getInstance().MyImport();
FaceServer.getInstance().getImgAndName(this);
mRegisterViewAdapter.notifyDataSetChanged();
}
2.FaceServer.java
中新增代码:
public void MyImport(){
synchronized (this) {
String path = Environment.getExternalStorageDirectory().getPath();
String SAVE_IMG_DIR2 = "register2" + File.separator + "imgs2";
String SAVE_FEATURE_DIR2 = "register2" + File.separator + "features2";
File imgfile = new File(path + File.separator + SAVE_IMG_DIR2);
if (!imgfile.exists() || !imgfile.isDirectory()) {
return;
}
File[] imgFiles = imgfile.listFiles();
if (imgFiles == null || imgFiles.length == 0) {
return;
}
File featurefile = new File(path + File.separator + SAVE_FEATURE_DIR2);
if (!featurefile.exists() || !featurefile.isDirectory()) {
return;
}
File[] featureFiles = featurefile.listFiles();
if (featurefile == null || featurefile.length() == 0) {
return;
}
MyimportFaceImgRegisterInfo = new ArrayList<>();
for (File imgFile : imgFiles) {
MyimportFaceImgRegisterInfo.add(new FaceImgRegisterInfo(imgFile.getPath(), imgFile.getName()));
}
MyimportFaceFeatureRegisterInfo = new ArrayList<>();
for (File featureFile : featureFiles) {
FileInputStream fis = null;
try {
fis = new FileInputStream(featureFile);
byte[] feature = new byte[FaceFeature.FEATURE_SIZE];
fis.read(feature);
fis.close();
MyimportFaceFeatureRegisterInfo.add(new FaceRegisterInfo(feature, featureFile.getName()));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//图片存储的文件夹
File imgDir = new File(ROOT_PATH + File.separator + SAVE_IMG_DIR);
if (!imgDir.exists() && !imgDir.mkdirs()) {
Log.e(TAG, "registerNv21: can not create image directory");
return;
}
for (FaceImgRegisterInfo img : MyimportFaceImgRegisterInfo) {
File file = new File(imgDir + File.separator + img.getName());
Bitmap bitmap = BitmapFactory.decodeFile(img.getImgpath());
FileOutputStream fosImage = null;
try {
fosImage = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fosImage);
fosImage.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//特征存储的文件夹
File featureDir = new File(ROOT_PATH + File.separator + SAVE_FEATURE_DIR);
if (!featureDir.exists() && !featureDir.mkdirs()) {
Log.e(TAG, "已建文件夹");
return;
}
for (FaceRegisterInfo feature : MyimportFaceFeatureRegisterInfo) {
File file = new File(featureDir + File.separator + feature.getName());
FileOutputStream fosFeature = null;
try {
fosFeature = new FileOutputStream(file);
fosFeature.write(feature.getFeatureData());
fosFeature.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.FaceServer.java中
public void MyImport(){
synchronized (this) {
String path = Environment.getExternalStorageDirectory().getPath();
String SAVE_IMG_DIR2 = "register" + File.separator + "imgs";
String SAVE_FEATURE_DIR2 = "register" + File.separator + "features";
4.导入后如下图:
11.人脸识别、活体检测和导入10000个人脸库zip下载
https://download.csdn.net/download/qq_35091074/18839315
12.419个人脸图片和特征zip下载
https://download.csdn.net/download/qq_35091074/18751114
13.即将下载10000
个 好期待
相关文章
- Android下载apk异常java.net.SocketTimeoutException: timeout解决办法
- android移动点餐系统内容和要求,基于Android云计算的移动点餐系统
- 《Android Studio开发实战 从零基础到App上线(第2版)》资源下载和内容勘误[通俗易懂]
- delphixe5 android,Delphi XE5 Android手机端转换Ansi字符串
- Android SDK下载和安装,以及部署「建议收藏」
- android 安装p12证书,如何在Android中使用p12证书(客户端证书)
- iphone4装android,iPhone4可安装Android实现双系统启动.pdf
- 常见的Android编译优化问题
- android scaleanimation动画,Android 动画之ScaleAnimation应用详解「建议收藏」
- 学习笔记 | Android开发常用的几种模式
- Android 数据库加密 android-database-sqlcipher 开源版本编译过程
- 【Android 系统开发】CyanogenMod 13.0 源码下载 编译 ROM 制作 ( 手机平台 : 小米4 | 编译平台 : Ubuntu 14.04 LTS 虚拟机)
- 【Android NDK 开发】Ubuntu 函数库交叉编译 ( Android 动态库交叉编译 | Android 静态库交叉编译 )
- 【错误记录】Flutter / Android 报错 ( AAPT: error: attribute android:requestLegacyExternalStorage not found )
- Android File Transfer (mac-安卓手机文件传输)
- 【Android 逆向】x86 汇编 ( call 子函数调用指令 | jmp 跳转指令 | lea 加载指令 | mov 数据传送指令 )
- 【Android 逆向】Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )
- 【Android 逆向】Frida 框架 ( Frida 2 种运行模式 | Frida 12.7.5 版本相关工具下载地址 | 在 Android 模拟器上运行 Frida 远程服务程序 )
- 【错误记录】编译 Android 版本的 ijkplayer 报错 ( You must define ANDROID_NDK before starting. | 下载指定版本 NDK )
- Android CircleImageView圆形ImageView详解手机开发
- ubuntu19系统及以下版本安装android studio的教程
- Android开发中遇到的问题(三)——eclipse创建android项目无法正常预览布局文件详解手机开发
- android开源项目下载地址详解手机开发
- Android多线程实现文件断点下载详解编程语言
- Office手机版下载 微软Android Office正式发布下载
- 在 VirtualBox 中安装 Android 系统
- Android实现PHP连接MySQL进行数据交互(android通过php连接mysql)
- MySQL下载ZIP包,解压安装教程(mysql下载的是zip)
- MySQL下载轻松获得ZIP版本(mysql下载下了zip)