Android移动开发-在Android项目里集成face++人脸识别的实现
来源:互联网 发布:扭力弩炮 知乎 编辑:程序博客网 时间:2024/04/30 10:36
“人工智能”是今年比较火的一个名词,甚至大多数人认为“人工智能”是继“IT互联网”之后一个新的浪潮,将会是本世纪最高科技的水准。个人觉得,目前国内语音识别做的比较好的是科大讯飞,图像识别(或人脸识别)做的比较好的是face++(旷视)。
那么,如何在Android项目里集成face++人脸识别的实现呢?
首先在face++的开发平台网址:https://www.faceplusplus.com.cn/ ,然后在平台注册成为开发者后在点击“应用管理”——创建“API Key”号,如下图所示:
接着再绑定Bundle ID号,如下图所示:
- layout/activity_main.xml界面布局代码如下:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <ImageView android:id="@+id/id_photo" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_alignTop="@+id/id_detect" android:src="@drawable/face" /> <TextView android:id="@+id/id_tip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignTop="@+id/id_detect" android:layout_marginRight="10dp" android:layout_toLeftOf="@+id/id_detect" android:gravity="center" android:text="tip" /> <Button android:id="@+id/id_detect" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginRight="10dip" android:layout_toLeftOf="@+id/id_getImg" android:text="检测人脸" /> <Button android:id="@+id/id_getImg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:text="选择图片" /> <FrameLayout android:id="@+id/id_waiting" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" android:visibility="gone"> <ProgressBar android:id="@+id/id_progressBar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> <TextView android:id="@+id/id_age_and_gender" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/hint" android:drawableLeft="@drawable/male" android:gravity="center" android:text="123" android:textColor="#ffff00ff" android:textSize="22sp" android:visibility="invisible" /> </FrameLayout></RelativeLayout>
- MainActivity.java逻辑代码如下:
package com.fukaimei.facerecognition;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import com.facepp.error.FaceppParseException;import com.fukaimei.facerecognition.utils.FaceppDetect;import android.content.Intent;import android.content.pm.PackageManager;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.net.Uri;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.provider.MediaStore;import android.support.annotation.NonNull;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v7.app.AppCompatActivity;import android.text.TextUtils;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends AppCompatActivity implements OnClickListener { private ImageView mPhoto; private Button mDetect, mGetImg; private TextView mTip; private View mWaiting; private Canvas canvas; private Paint mPaint; private String mCurrentPhotoStr; private Bitmap mBitmapPhoto; private static final int PICK_CODE = 0x110; private static final int MSG_SUCCESS = 0x111; private static final int MSG_ERROR = 0x112; private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case MSG_SUCCESS: mWaiting.setVisibility(View.GONE); JSONObject rs = (JSONObject) msg.obj; prepareResultBitmap(rs); mPhoto.setImageBitmap(mBitmapPhoto); break; case MSG_ERROR: mWaiting.setVisibility(View.GONE); String errorMsg = (String) msg.obj; if (TextUtils.isEmpty(errorMsg)) { mTip.setText("Error."); } else { mTip.setText(errorMsg); } break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 申请访问SD卡的动态权限 sdPermissions(); mPhoto = (ImageView) findViewById(R.id.id_photo); mDetect = (Button) findViewById(R.id.id_detect); mGetImg = (Button) findViewById(R.id.id_getImg); mTip = (TextView) findViewById(R.id.id_tip); mWaiting = findViewById(R.id.id_waiting); mDetect.setOnClickListener(this); mGetImg.setOnClickListener(this); mPaint = new Paint(); } // 定义访问SD卡的动态权限 private void sdPermissions() { if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{ android.Manifest.permission.READ_EXTERNAL_STORAGE}, 1); } } /** * 重写onRequestPermissionsResult方法 * 获取动态权限请求的结果,再访问SD卡 */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { } else { Toast.makeText(this, "用户拒绝了权限", Toast.LENGTH_SHORT).show(); } super.onRequestPermissionsResult(requestCode, permissions, grantResults); } private void prepareResultBitmap(JSONObject rs) { // TODO Auto-generated method stub Bitmap bitmap = Bitmap.createBitmap(mBitmapPhoto.getWidth(), mBitmapPhoto.getHeight(), mBitmapPhoto.getConfig()); canvas = new Canvas(bitmap); canvas.drawBitmap(mBitmapPhoto, 0, 0, null); try { JSONArray faces = rs.getJSONArray("face"); int faceCount = faces.length(); mTip.setText("find " + faceCount); for (int i = 0; i < faceCount; i++) { // 拿到单独face对象 JSONObject face = faces.getJSONObject(i); JSONObject positonObj = face.getJSONObject("position"); // get face position float x = (float) positonObj.getJSONObject("center").getDouble("x"); float y = (float) positonObj.getJSONObject("center").getDouble("y"); float w = (float) positonObj.getDouble("width"); float h = (float) positonObj.getDouble("height"); x = x / 100 * bitmap.getWidth(); y = y / 100 * bitmap.getHeight(); w = w / 100 * bitmap.getWidth(); h = h / 100 * bitmap.getHeight(); mPaint.setColor(0xffffffff); mPaint.setStrokeWidth(3); // draw box canvas.drawLine(x - w / 2, y - h / 2, x - w / 2, y + h / 2, mPaint);// 左 canvas.drawLine(x - w / 2, y + h / 2, x + w / 2, y + h / 2, mPaint);// 下 canvas.drawLine(x + w / 2, y + h / 2, x + w / 2, y - h / 2, mPaint);// 右 canvas.drawLine(x - w / 2, y - h / 2, x + w / 2, y - h / 2, mPaint);// 上 // get age and gender int age = face.getJSONObject("attribute").getJSONObject("age").getInt("value"); String gender = face.getJSONObject("attribute").getJSONObject("gender").getString("value"); Bitmap ageBitmap = buildAgeBitmap(age, gender.equals("Male")); int ageWidth = ageBitmap.getWidth(); int ageHeight = ageBitmap.getHeight(); if(bitmap.getWidth()<=mPhoto.getWidth() && bitmap.getHeight()<=mPhoto.getHeight()){ float ratio = Math.max(bitmap.getWidth() * 1.0f / mPhoto.getWidth(), bitmap.getHeight() * 1.0f / mPhoto.getHeight()); ageBitmap = Bitmap.createScaledBitmap(ageBitmap, (int) (ageWidth * ratio), (int) (ageHeight * ratio), false); canvas.drawBitmap(ageBitmap, x - ageBitmap.getWidth() / 2, y - h / 2 - ageBitmap.getHeight(), null); } mBitmapPhoto = bitmap; } } catch (JSONException e) { e.printStackTrace(); } }; private Bitmap buildAgeBitmap(int age, boolean isMale) { TextView tv = (TextView) mWaiting.findViewById(R.id.id_age_and_gender); tv.setText(age + ""); if (isMale) { tv.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.male), null, null, null); } else { tv.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.female), null, null, null); } tv.setDrawingCacheEnabled(true); Bitmap bitmap = Bitmap.createBitmap(tv.getDrawingCache()); tv.destroyDrawingCache(); return bitmap; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PICK_CODE) { if (data != null) { Uri uri = data.getData(); Cursor cursor = getContentResolver().query(uri, null, null, null, null); cursor.moveToFirst(); int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); mCurrentPhotoStr = cursor.getString(index); cursor.close(); resizePhoto(); mPhoto.setImageBitmap(mBitmapPhoto); mTip.setText("点击检测 ==>"); } } super.onActivityResult(requestCode, resultCode, data); } private void resizePhoto() { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(mCurrentPhotoStr, options); double ratio = Math.max(options.outWidth * 1.0d / 1024f, options.outHeight * 1.0d / 1024f); options.inSampleSize = (int) Math.ceil(ratio); options.inJustDecodeBounds = false; mBitmapPhoto = BitmapFactory.decodeFile(mCurrentPhotoStr, options); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.id_getImg: Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, PICK_CODE); break; case R.id.id_detect: if (mBitmapPhoto != null && !mBitmapPhoto.isRecycled()) { mWaiting.setVisibility(View.VISIBLE); FaceppDetect.detect(mBitmapPhoto, new FaceppDetect.CallBack() { @Override public void success(JSONObject result) { Message msg = mHandler.obtainMessage(MSG_SUCCESS); msg.obj = result; msg.sendToTarget(); } @Override public void error(FaceppParseException exception) { Message msg = mHandler.obtainMessage(MSG_ERROR); msg.obj = exception.getErrorMessage(); msg.sendToTarget(); } }); } else { Toast.makeText(MainActivity.this, "请选择您要检测的人脸图片", Toast.LENGTH_SHORT).show(); } break; } }}
- 然后在 Constant.java逻辑代码下添加在face++平台申请到的APP_KEY码和APP_SECRET码如下:
package com.fukaimei.facerecognition;public class Constant { public static final String APP_KEY = "填写你申请到的APP_KEY码"; public static final String APP_SECRET = "填写你申请到的APP_SECRET码";}
- Demo程序运行效果界面截图如下:
Demo程序源码下载地址一(GitHub)
Demo程序源码下载地址二(Gitee)
阅读全文
1 0
- Android移动开发-在Android项目里集成face++人脸识别的实现
- Android移动开发-在Android项目里集成讯飞语音识别与合成的实现
- Android移动开发-在Android项目里集成调用支付宝支付开发的实现
- Android移动开发-在Android项目里集成调用微信支付开发的实现
- Face++人脸识别 android studio开发集成
- Android移动开发-在Android项目里集成开源框架ZXing实现扫描二维码的功能
- Android移动开发-在Android应用里集成QQ分享的实现
- 使用face++接口实现在Android设备上的人脸识别
- Android移动开发-在Android项目里调用基于百度地图API实现定位
- Android移动开发-在Android项目里调用基于高德地图API实现定位
- Android使用Face++架构包实现人脸识别
- 在树莓派上实现face++人脸识别
- Face++ 人脸识别,身份识别集成
- 3、基于Face++开发的一款人脸识别App:Android-HowOld
- 【Android】测试Face++的人脸识别算法
- face++实现人脸识别
- face++实现人脸识别
- face ++ 实现人脸识别
- CSS核对
- CCF CSP 网络延时 JAVA 201503_4 100分
- android studio在终端执行gradlew命令,报无效的环境
- eclipseUnable to build: the file dx.jar was not loaded from the SDK folder 错误
- 1.UE4入门篇
- Android移动开发-在Android项目里集成face++人脸识别的实现
- 常用正则表达式爬取网页信息及分析HTML标签总结
- 函数的调用过程(栈帧)
- 使用spring cloud config来统一管理配置文件
- 赋值中的类型转换
- vue生命周期及自定义指令
- python学习笔记--一些常用的tip
- 协方差矩阵
- 内置函数和匿名函数