本项目采用了 Face++人脸识别 第三方接口,实现了自选本地手机相册图片上传人脸(faceSet中添加人脸) 和 自选本地手机相册图片寻找出集合中相似度最高的一个face,可返回比对相似度等信息。

项目具体步骤如下:

一 、所需权限

    <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

二、第三方app id app key

项目采用了Face++第三方接口,可自行注册获取

三、添加依赖和sdk

1. 将FaceppSDK.jar文件放到libs路径下。

2. gradle中添加一下依赖:

//导入sdk
compile files('libs/FaceppSDK.jar')

四、布局文件

人脸寻找1:n

主要代码:

 <?xml version="1.0" encoding="utf-8"?>
<ScrollView
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="com.example.lifen.facesearchdemo.MainActivity"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="1"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <ImageView
android:id="@+id/img1"
android:layout_width="0dp"
android:layout_height="180dp"
android:layout_weight="1.02"
android:scaleType="centerCrop"
android:src="@drawable/head"/> <ScrollView
android:layout_weight="0.74"
android:layout_width="60dp"
android:layout_height="match_parent">
<TextView
android:id="@+id/addRresultTV"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="添加结果"
android:textColor="@android:color/black" />
</ScrollView> </LinearLayout> <EditText
android:id="@+id/uidEt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="请输入uid(名字)"
android:inputType="textPersonName" /> <Button
android:id="@+id/addFaceBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加" /> <Button
android:id="@+id/searchBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_horizontal_margin"
android:text="寻找" /> <TextView
android:id="@+id/resultBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_horizontal_margin"
android:background="#eeeeee"
android:padding="6dp"
android:layout_weight="2.94" /> </LinearLayout>
</ScrollView>

页面包含:

  ① ImageView 点击ImageView 可跳转手机相册,选择要使用的图片。

  ② TextView1  faceSet添加face 结果再次显示

  ③ EditText 设定face 的user_uid

  ④ button1 添加人脸按钮

  ⑤ button2 寻找相似度最高人脸按钮

  ⑥ TextView2 寻找结果展示view

 faceSet 中添加 face过程:

  1. 点击imageView 选取图片

  2. 输入uid

  3. 点击添加

 寻找相似度最高face过程:

  1.点击imageView 选取图片

  2. 点击寻找按钮

五、页面activity

主要代码:

 package com.example.lifen.facesearchdemo;

 import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast; import com.megvii.cloud.http.CommonOperate;
import com.megvii.cloud.http.FaceOperate;
import com.megvii.cloud.http.FaceSetOperate;
import com.megvii.cloud.http.Response; import org.json.JSONException;
import org.json.JSONObject; import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList; /**
* 人脸对比 1:1
*
* @author LiFen
*/
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final int REQUEST_CODE1 = 11;
ImageView mImageView1;
Button mSearchBtn;
private Button mAddFaceBtn;
TextView mResultText;
private TextView mAddResultText;
private String mImgBase641;
private EditText uidEidtText;
ArrayList<String> faces = new ArrayList<>();
String key = "";//api_key
String secret = "";//api_secret
private final static int i = 100;
private final static int j = 200;
private final static int s = 300;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what == i){
mAddResultText.setText((String)msg.obj);
}
if(msg.what == j){
mAddResultText.append((String)msg.obj);
}
if(msg.what == s){
mResultText.setText((String)msg.obj);
}
}
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mImageView1 = (ImageView) findViewById(R.id.img1);
mSearchBtn = (Button) findViewById(R.id.searchBtn);
mAddFaceBtn = (Button)findViewById(R.id.addFaceBtn);
mResultText = (TextView) findViewById(R.id.resultBtn);
mAddResultText = (TextView)findViewById(R.id.addRresultTV);
uidEidtText = (EditText)findViewById(R.id.uidEt);
if(TextUtils.isEmpty(key) || TextUtils.isEmpty(secret)){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("please enter key and secret");
builder.setTitle("");
builder.show();
return;
}
mImageView1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startAlbumActivity(REQUEST_CODE1);
}
});
mAddFaceBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addFace();
}
});
mSearchBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startSearch();
}
});
} private void addFace(){
if ("".equals(mImgBase641) || mImgBase641 == null) {
Toast.makeText(this, "请选择图片再添加", Toast.LENGTH_SHORT).show();
return;
}
if(uidEidtText.getText().toString().equals("")){
Toast.makeText(this,"请输入uid(名字)",Toast.LENGTH_SHORT).show();
return;
}
mResultText.setText("人脸添加中...");
new Thread(new Runnable() {
@Override
public void run() {
CommonOperate commonOperate = new CommonOperate(key, secret, false);
try{
//获取faceToken
Response response = commonOperate.detectBase64(mImgBase641, 0, null);
FaceOperate faceOperate = new FaceOperate(key,secret,false);
String faceToken = getFaceToken(response);
String uid = uidEidtText.getText().toString();
Log.i(TAG, "run: " + uid);
faceOperate.faceSetUserId(faceToken, uid);
faces.add(faceToken);
Message msg = new Message();
msg.what = i;
msg.obj = faceToken;
handler.sendMessage(msg);
//faceSet中添加faceToken
FaceSetOperate FaceSet = new FaceSetOperate(key, secret, false);
String faceTokens = creatFaceTokens(faces);
Response faceSet = FaceSet.addFaceByFaceToken(faceTokens, "469e42d27947506b44cee9a8dba2eb4f");
String result = new String(faceSet.getContent());
msg.what = j;
msg.obj = result;
handler.sendMessage(msg);
}catch (Exception e){
Log.i(TAG, "addFace: " +e.toString());
}
}
}).start();
} private void startSearch() {
if ("".equals(mImgBase641) || mImgBase641 == null) {
Toast.makeText(this, "请选择图片再寻找", Toast.LENGTH_SHORT).show();
return;
}
mResultText.setText("搜索比对中...");
new Thread(new Runnable() {
@Override
public void run() {
Log.i(TAG, "run() called");
CommonOperate commonOperate = new CommonOperate(key, secret, false);
//获取faceToken
Response response = null;
try {
response = commonOperate.detectBase64(mImgBase641, 0, null);
String faceToken = getFaceToken(response);
Response searchByOuterId = commonOperate.searchByOuterId(faceToken, null, null, "test", 1);
Message msg = new Message();
msg.what = s;
String result = new String(searchByOuterId.getContent());
msg.obj = result;
handler.sendMessage(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
} private void startAlbumActivity(int requestCode) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, requestCode);
} @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null)
return;
Uri uri = data.getData();
Log.e("uri", uri.toString());
ContentResolver cr = this.getContentResolver();
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri));
/* 将Bitmap设定到ImageView */
} catch (FileNotFoundException e) {
Log.e("Exception", e.getMessage(), e);
}
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE1) {
mImageView1.setImageBitmap(bitmap);
mImgBase641 = bitmapToBase64(bitmap);
}
super.onActivityResult(requestCode, resultCode, data);
} private String bitmapToBase64(Bitmap bitmap) {
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bStream);
return Base64.encodeToString(bStream.toByteArray(), 0);
} private String getFaceToken(Response response) throws JSONException {
if(response.getStatus() != 200){
return new String(response.getContent());
}
String res = new String(response.getContent());
Log.e("response", res);
JSONObject json = new JSONObject(res);
String faceToken = json.optJSONArray("faces").optJSONObject(0).optString("face_token");
return faceToken;
} private String creatFaceTokens(ArrayList<String> faceTokens){
if(faceTokens == null || faceTokens.size() == 0){
return "";
}
StringBuffer face = new StringBuffer();
for (int i = 0; i < faceTokens.size(); i++){
if(i == 0){
face.append(faceTokens.get(i));
}else{
face.append(",");
face.append(faceTokens.get(i));
}
}
return face.toString();
}
}

其中key 和 secret 可自行注册填入。本项目之前已经创建了faceSet,创建过程可参考:https://download.csdn.net/download/qq_36726507/10293566

注意:uid 不超过255个字符,不能包括^@,&=*'",不可使用中文(用中文挂掉好几次)。

项目地址:https://download.csdn.net/download/qq_36726507/10293600

人脸识别1:n对比 (一)的更多相关文章

  1. Android 虹软人脸识别SDK-人脸对比

    准备 : 登录官方网站,获取SDK,进行个人验证后新建项目,获取APP_ID,和SDK_KEY: https://ai.arcsoft.com.cn/ucenter/resource/build/in ...

  2. iOS 使用百度的人脸识别登录验证,解决认证失败不跳转界面连续认证,认证相似度对比

    在使用百度人脸识别出现的问题:小米6调用摄像机是黑白的一个情况,iOS上会出现识别准确性上的问题(多次代开认证,会通过) 人脸识别(活体验证): 1.芝麻认证 : 0.4元/次,需要企业企业认证.不能 ...

  3. ArcFace虹软与Dlib人脸识别对比

    我司最近要做和人脸识别相关的产品,原来使用的是其他的在线平台,识别率和识别速度很满意,但是随着量起来的话,成本也是越来越不能接受(目前该功能我们是免费给用户使用的),而且一旦我们的设备掉线了就无法使用 ...

  4. 人脸识别1:n对比 (二)

    本项目采用了百度AI 人脸识别 第三方接口,实现了自选本地手机相册图片上传人脸(faceSet中添加人脸) 和 自选本地手机相册图片寻找出集合中相似度最高的一个face,可返回比对相似度.位置等信息. ...

  5. arcface和Dlib人脸识别算法对比

    我司最近要做和人脸识别相关的产品,原来使用的是其他的在线平台,识别率和识别速度很满意,但是随着量起来的话,成本也是越来越不能接受(目前该功能我们是免费给用户使用的),而且一旦我们的设备掉线了就无法使用 ...

  6. 关于dlib人脸对比,人脸识别

    人脸检测 人脸特征点提取 人脸对比,等于两张人脸对比,识别 封装的所有识别函数,直接看下面调用就好了. # coding:utf-8 ''' 本本次封装,我主要是做两张人脸对比. 就只人脸识别部分,简 ...

  7. 基于node.js人脸识别之人脸对比

    基于node.js人脸识别之人脸对比 Node.js简介 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. Node.js 使用了一个事件驱动.非阻塞式 I/O ...

  8. 关于opencv中人脸识别主函数的部分注释详解。

    近段时间在搞opencv的视频人脸识别,无奈自带的分类器的准确度,实在是不怎么样,但又能怎样呢?自己又研究不清楚各大类检测算法. 正所谓,功能是由函数完成的,于是自己便看cvHaarDetectObj ...

  9. Opencv摄像头实时人脸识别

    Introduction 网上存在很多人脸识别的文章,这篇文章是我的一个作业,重在通过摄像头实时采集人脸信息,进行人脸检测和人脸识别,并将识别结果显示在左上角. 利用 OpenCV 实现一个实时的人脸 ...

随机推荐

  1. flask+redis实现抢购(秒杀)功能

    今天面试了 一家非常高大上的公司,问了我关于redis的实用性问题,但是答的不是很好,所以下午通过再次学习 redis,实现相关实用性功能的一种. 对于抢购功能,难点在于 抢购时 由于高并发请求,导致 ...

  2. 自动生成 java 测试 mock 对象框架 DataFactory-01-入门使用教程

    项目简介 Data-Factory 用于根据对象,随机自动生成初始化信息,避免了手动创建对象的繁琐,便于测试. 特性 8 大基本类型的支持 String.Date.金额,日期等常见类型的支持 java ...

  3. shell脚本实现telnet测试服务端口

    备注,使用方法:当前目录下要存在需要测试的地址端口的文件ip.txt,例子:cat ip.txt141.12.65.17 7500 #!/bin/bashcur_dir=$(pwd)ipfile=$c ...

  4. c博客作业01--顺序、分支结构

    1.本章学习总结 1.1思维导图 1.2本章的学习体会及代码量学习体会 1.2.1学习体会 本周学习的感受:原先基础是0的,所以本周学习起来并不是很轻松,有很多知识运用的 不是很熟,但是基本的知识是能 ...

  5. websocket的子协议stomp协议

    stomp协议Spring实现 服务器注册EndPoint 用来与客户端建立websocket连接 websocket连接的建立应该与客户端与服务器之间的通道无关 jdk中 javax下的websoc ...

  6. C# 构造函数中base和this的使用。

    使用base时,首先给父类中的构造函数赋值. 使用this时,先调用父类无参构造函数,再调用自身其他构造函数并对其赋值,最后调用自身当前构造函数.

  7. Java解法-两数相加(Add Two Numbers)

    问题  给出两个非空的链表用来表示两个非负的整数.其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和. ...

  8. React 获取服务器API接口数据:axios、fetchJsonp

    使用axios.fetchJsonp获取服务器的接口数据.其中fetchJsonp是跨域访问 一.使用axios 1.安装axios模块 npm install --save axios 2.引用模块 ...

  9. spring boot 2.0.4 Redis缓存配置

    spring boot 2 使用RedisTemplate操作redis存取对象时,需要先进行序列化操作 import org.springframework.cache.CacheManager; ...

  10. Linux yum源

    (一)yum源概述 yum需要一个yum库,也就是yum源.默认情况下,CentOS就有一个yum源.在/etc/yum.repos.d/目录下有一些默认的配置文件(可以将这些文件移到/opt下,或者 ...