作者 : 不良使
潜力创作新星 华为云享专家
博客记录学习的思路,项目和错误,寻找志同道合的朋友
如果觉得有帮助记得一键三连 ┗|`O′|┛ 嗷~~
想要给你的项目加上人脸识别的亮点吗,那就来看看这篇文章吧。本次实验通过使用讯飞开放平台上MSC人脸识别能力,介绍了人脸验证与人脸检索的使用,结合服务机器人的相机能力,开发一个简单的人脸识别应用程序,了解人脸识别技术如何在机器人上使用,同时对人脸识别技术的使用途径和步骤进行详细讲解,具体包括下面三个部分:
1、了解讯飞开放平台MSC的人脸识别技术;
2、 掌握机器人开发套件相机的使用;
3、 掌握人脸识别功能在机器人上的应用开发。
人脸识别作为一项热门的计算机技术研究领域,是利用分析比较的计算机技术识别人脸,其中包括人脸追踪侦测,自动调整影像放大,夜间红外侦测,自动调整曝光强度等技术。人脸识别技术属于生物特征识别技术,是对生物体(一般特指人)本身的生物特征来区分生物体个体。本次实验就是通过一个智能人脸识别应用的开发,来向大家展示人脸识别技术在智能AI应用中的具体实现方法和呈现的效果体验。本次实验通过开发一个实际的简单智能人脸识别应用,通过机器人完成人脸的注册与识别,并对具体的技术与流程做详细的讲解。
由于本次实验开发的人脸识别功能应用使用的是科大讯飞开放平台提供的 人脸识别能力,我们需要先到讯飞的开放平台申请账号,并完成平台上相关能力 注册,具体流程如下: 1)首先,我们要在讯飞开放平台进行账号注册,地址:https://www.xfyun.cn/
此时,进入“我的应用”界面,可以看到添加的应用信息,包括 appid 等,点 击“其他”,在弹出的界面中选择“人脸验证与检索”的管理服务,可以选择对 应的服务完成 SDK 的下载
在其他中找到人脸识别,下载对应的SDK。
完成了工程项目的搭建后,我们需要在项目工程中集成开放平台的MSC能力,具体步骤如下:
首先,将MSC能力包文件mscability-release.aar文件拷贝到项目工程的/app/libs目录下;
然后,解压从讯飞开放平台下载的人脸识别SDK能力包,在libs目录下找到Msc.jar文件,拷贝到项目工程目录/app/libs目录下;接着,将SDK能力包libs目录下的所有armeabi目录拷贝到工程目录/app/src/main/jniLibs下(若没有这个目录,自己创建)。整体目录结构如下:
完成SDK的集成后,我们需要再编译配置文件中进行能力包的导入配置,打开app目录下的build.gradle文件,添加下图中红框位置中代码
完整的build.gradle文件如下所示:
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.starway.starrobot"
minSdkVersion 18
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
//只需要兼容armeabi-v7a
abiFilters "armeabi-v7a"
}
}
signingConfigs {
debug {
storeFile file("platform.jks")
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
release {
storeFile file("platform.jks")
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
首先,在我们的应用工程新建我们自定义的Application(MyApp.java),在MyApp.java文件的onCreate中进行开放平台MSC能力的注册,只有完成了能力的注册后,才能使用人脸识别的能力接口。
private void init() {
StarMscAbility.getInstance().initWithAppid(getApplicationContext(), APPID);
//日志初始化
StarLogAbility.getInstance().initAbility(this);
//基础能力初始化
StarCommonAbility.getInstance().initAbility(this,
RobotType.TYPE_TEACHING, new StarCommonAbility.onResultCallback() {
@Override
public void onResult(boolean isSuccess, String hardCode) {
if (isSuccess) {
//硬件和业务状态初始化
switch (hardCode) {
case PartCode.HARDWARE_PARTCODE.CODE_EMOJI:
//设置初始表情
EmojiHelper.doEmojiBase();
break;
case PartCode.HARDWARE_PARTCODE.CODE_GPIO:
//默认加载的时候,将拾音方向设置为默认正前方的0度。
GPIOHelper.getInstance().setMainMic(0);
break;
case PartCode.HARDWARE_PARTCODE.CODE_CENTER_LIGHT:
//关闭腹部灯带
CenterLightHelper.takeCenterLightOff();
break;
default:
break;
}
}
}
});
}
界面控件初始化(部分)
private void initView() {
//组ID显示text
mTxtGroupid = findViewById(R.id.groupid);
//人脸标识显示text
mEdtAuthid = findViewById(R.id.online_authid);
//界面按钮点击处理
findViewById(R.id.group_create).setOnClickListener(this);
findViewById(R.id.group_delete).setOnClickListener(this);
findViewById(R.id.online_register).setOnClickListener(this);
findViewById(R.id.take_pic).setOnClickListener(this);
findViewById(R.id.recognition_face).setOnClickListener(this);
//提前创建一个组进行组的设置
mTxtGroupid.setText("******");
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.group_create: //创建组
createGroup();
break;
case R.id.group_delete: //删除组
deleteGroup(mGroupId);
break;
case R.id.online_register: //在线注册人脸信息
registerFace();
break;
case R.id.take_pic: //拍摄照片
Intent mIntent = new Intent(MainActivity.this, CameraActivity.class);
startActivityForResult(mIntent, 1000);
break;
case R.id.recognition_face: //识别照片中的人脸信息
recognitionFace();
break;
}
}
/**
* 创建组
*/
private void createGroup() {
// 创建人脸组
faceGroupHelper.createGroup(new StarMscAbility.onResultCallback() {
@Override
public void onResult(boolean flag, String result) {
Log.d("MainActivity", "result = " + flag + " groupId = " + result);
if (flag) {
mGroupId = result;
mTxtGroupid.setText(result);
showToast("创建组成功:" + result + "-请牢记你的GroupId!!!");
} else {
showToast("创建组失败:" + result);
}
}
});
}
/**
* 删除组
*/
private void deleteGroup(String groupid) {
if (mGroupId.equals("")) {
showToast("Please Create GroupId Frist");
return;
}
faceGroupHelper.deleteGroup(groupid, new StarMscAbility.onResultCallback() {
@Override
public void onResult(boolean flag, String result) {
if (flag) {
mTxtGroupid.setText("");
showToast("删除组成功");
} else {
showToast("删除组失败" + result);
}
}
});
}
/**
* 人脸注册
*/
private void registerFace() {
if (mGroupId.equals("")) {
showToast("Please Create GroupId Frist");
return;
}
if (mImage == null) {
showToast("请拍照");
}
if (null == mEdtAuthid.getText() || mEdtAuthid.getText().toString().equals("")) {
showToast("请输入userId");
}
userId = mEdtAuthid.getText().toString();
faceRegisterHelper = new FaceRegisterHelper(this);
faceRegisterHelper.startRegister(userId, mImage,
new StarMscAbility.onResultCallback() {
@Override
public void onResult(boolean flag, String result) {
if (flag) {
showToast("人脸模型注册成功:" + mEdtAuthid.getText());
//注册成功后加组
faceGroupHelper.addFace(userId, mGroupId, new StarMscAbility.onResultCallback() {
@Override
public void onResult(boolean flag, String result) {
Log.d("MainActivity", "result = " + result);
if (flag) {
showToast("人脸注册加组成功:" + result);
} else {
showToast("人脸注册加组失败:" + result);
}
}
});
} else {
showToast("注册模型注册失败:" + result);
}
}
});
}
/**
* 人脸识别
*/
private void recognitionFace() {
if (mGroupId.equals("")) {
showToast("Please Create GroupId First");
return;
}
if (mImage == null) {
showToast("请拍照");
}
faceVerifyHelper.setFaceVerifyResultCallback(new StarMscAbility.onResultCallback() {
@Override
public void onResult(boolean flag, String result) {
//返回参数flag为人脸识别结果
//当flag为true时,result为空,表示图片中检测到了人脸,但没有匹配到人脸库中的人脸信息,当msg不为空时,msg的值表示匹配到的人脸结果(注册时提交的人脸标识)
//当flag为false时,result的值表示人脸识别失败的信息(包括图片中没有检测到人脸)
if (flag) {
if ("".equals(result)) {
showToast("该人脸还未注册!");
} else {
showToast("识别成功,欢迎您:" + result);
}
} else {
showToast("没有匹配到人脸");
}
}
});
faceVerifyHelper.sendGroupVerify(mGroupId,mImage);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode,resultCode,data);
if (resultCode != RESULT_OK) {
return;
}
String fileSrc = null;
if (requestCode == 1000) {
fileSrc = data.getStringExtra("bitmap");
if (null != fileSrc) {
// mPath = fileSrc;
// 获取图片的宽和高
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
// 压缩图片
options.inSampleSize = Math.max(1, (int) Math.ceil(Math.max(
(double) options.outWidth / 512f,
(double) options.outHeight / 512f)));
mImage = BitmapFactory.decodeFile(fileSrc, options);
// 若mImageBitmap为空则图片信息不能正常获取
if (null == mImage) {
showToast("图片信息无法正常获取!");
return;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//可根据流量及网络状况对图片进行压缩
mImage.compress(Bitmap.CompressFormat.JPEG, 80, baos);
// mImageData = baos.toByteArray();
((ImageView) findViewById(R.id.online_img)).setImageBitmap(mImage);
}
}
}
/**
* 显示toast提升信息
*
* @param value
*/
private void showToast(String value) {
Toast.makeText(this, value, Toast.LENGTH_SHORT).show();
}
}
跟以前在安装 APP 的是就申请了权限不同,Google 在 API 23,也就 Android6.0 之后加入了动态权限。对于一些敏感的权限,决定权交还给了用户, 不再是强制申请了。因为这个原因,如果 APP 需要支持 Android6.0 以上的系 文档密级:外部公开 20 统,就需要进行一下适配,否则 APP 就会崩溃。 除了进入设置手动开启权限,还有两种方式让应用获得权限:动态权限申请、 平台签名。本次实验我们采用平台签名的方式获得权限。
由上图可知试验成功,可以通过摄像头捕捉到我(注意:此处应该先创建group,然后再人脸识别)
具体流程如下:
1、我们先点击“创建Group”按钮,创建人脸组,完成人脸组的创建后,界面上会显示组ID信息;
2、然后我们点击“拍照”按钮,使用机器人开发平台的摄像头对准脸部进行拍照,完成后,界面上会显示照片信息,确保照片包含完整的人脸图片;
3、在用户标识输入框里面输入人脸标识信息,使用字母+数字的方式,然后点击“人脸注册”按钮,注册成功会弹出提示信息;
4、熟悉了人脸注册的方法,我们可以找不同的人按照同样的方式多注册几个人脸信息;
5、完成了人脸信息的注册后,我们使用摄像头再进行拍照,然后点击“人脸识别”按钮,查看是否对已经注册过的人脸信息能够准确的进行识别。
1)Android 开发工具网站
2)Android 开发者社区
3)科大讯飞 AIUI 开放平台
4)科大讯飞开放平台文档中心
觉得有用的可以给个三连,关注一波!!!带你了解更多的智能机器人小知识