zoukankan      html  css  js  c++  java
  • 人脸识别1:n对比 (一)

      本项目采用了 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

    主要代码:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <ScrollView
     3     xmlns:android="http://schemas.android.com/apk/res/android"
     4     xmlns:tools="http://schemas.android.com/tools"
     5     android:layout_width="match_parent"
     6     android:layout_height="match_parent"
     7     android:paddingBottom="@dimen/activity_vertical_margin"
     8     android:paddingLeft="@dimen/activity_horizontal_margin"
     9     android:paddingRight="@dimen/activity_horizontal_margin"
    10     android:paddingTop="@dimen/activity_vertical_margin"
    11     tools:context="com.example.lifen.facesearchdemo.MainActivity">
    12 
    13     <LinearLayout
    14         android:layout_width="match_parent"
    15         android:layout_height="match_parent"
    16         android:orientation="vertical"
    17         android:weightSum="1">
    18 
    19         <LinearLayout
    20             android:layout_width="match_parent"
    21             android:layout_height="wrap_content"
    22             android:orientation="horizontal">
    23 
    24             <ImageView
    25                 android:id="@+id/img1"
    26                 android:layout_width="0dp"
    27                 android:layout_height="180dp"
    28                 android:layout_weight="1.02"
    29                 android:scaleType="centerCrop"
    30                 android:src="@drawable/head"/>
    31 
    32             <ScrollView
    33                 android:layout_weight="0.74"
    34                 android:layout_width="60dp"
    35                 android:layout_height="match_parent">
    36                 <TextView
    37                     android:id="@+id/addRresultTV"
    38                     android:layout_width="match_parent"
    39                     android:layout_height="match_parent"
    40                     android:gravity="center"
    41                     android:text="添加结果"
    42                     android:textColor="@android:color/black" />
    43             </ScrollView>
    44 
    45         </LinearLayout>
    46 
    47         <EditText
    48             android:id="@+id/uidEt"
    49             android:layout_width="match_parent"
    50             android:layout_height="wrap_content"
    51             android:ems="10"
    52             android:hint="请输入uid(名字)"
    53             android:inputType="textPersonName" />
    54 
    55         <Button
    56             android:id="@+id/addFaceBtn"
    57             android:layout_width="match_parent"
    58             android:layout_height="wrap_content"
    59             android:text="添加" />
    60 
    61         <Button
    62             android:id="@+id/searchBtn"
    63             android:layout_width="match_parent"
    64             android:layout_height="wrap_content"
    65             android:layout_marginTop="@dimen/activity_horizontal_margin"
    66             android:text="寻找" />
    67 
    68         <TextView
    69             android:id="@+id/resultBtn"
    70             android:layout_width="match_parent"
    71             android:layout_height="wrap_content"
    72             android:layout_marginTop="@dimen/activity_horizontal_margin"
    73             android:background="#eeeeee"
    74             android:padding="6dp"
    75             android:layout_weight="2.94" />
    76 
    77     </LinearLayout>
    78 </ScrollView>
    View Code

    页面包含:

      ① 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

    主要代码:

      1 package com.example.lifen.facesearchdemo;
      2 
      3 import android.content.ContentResolver;
      4 import android.content.Intent;
      5 import android.graphics.Bitmap;
      6 import android.graphics.BitmapFactory;
      7 import android.net.Uri;
      8 import android.os.Bundle;
      9 import android.os.Handler;
     10 import android.os.Message;
     11 import android.support.v7.app.AlertDialog;
     12 import android.support.v7.app.AppCompatActivity;
     13 import android.text.TextUtils;
     14 import android.util.Base64;
     15 import android.util.Log;
     16 import android.view.View;
     17 import android.widget.Button;
     18 import android.widget.EditText;
     19 import android.widget.ImageView;
     20 import android.widget.TextView;
     21 import android.widget.Toast;
     22 
     23 import com.megvii.cloud.http.CommonOperate;
     24 import com.megvii.cloud.http.FaceOperate;
     25 import com.megvii.cloud.http.FaceSetOperate;
     26 import com.megvii.cloud.http.Response;
     27 
     28 import org.json.JSONException;
     29 import org.json.JSONObject;
     30 
     31 import java.io.ByteArrayOutputStream;
     32 import java.io.FileNotFoundException;
     33 import java.util.ArrayList;
     34 
     35 /**
     36  * 人脸对比 1:1
     37  *
     38  * @author LiFen
     39  */
     40 public class MainActivity extends AppCompatActivity {
     41     private static final String TAG = "MainActivity";
     42     private static final int REQUEST_CODE1 = 11;
     43     ImageView mImageView1;
     44     Button mSearchBtn;
     45     private Button mAddFaceBtn;
     46     TextView mResultText;
     47     private TextView mAddResultText;
     48     private String mImgBase641;
     49     private EditText uidEidtText;
     50     ArrayList<String> faces = new ArrayList<>();
     51     String key = "";//api_key
     52     String secret = "";//api_secret
     53     private final static int i = 100;
     54     private final static int j = 200;
     55     private final static int s = 300;
     56     private Handler handler = new Handler(){
     57         @Override
     58         public void handleMessage(Message msg) {
     59             if(msg.what == i){
     60                 mAddResultText.setText((String)msg.obj);
     61             }
     62             if(msg.what == j){
     63                 mAddResultText.append((String)msg.obj);
     64             }
     65             if(msg.what == s){
     66                 mResultText.setText((String)msg.obj);
     67             }
     68         }
     69     };
     70 
     71     @Override
     72     protected void onCreate(Bundle savedInstanceState) {
     73         super.onCreate(savedInstanceState);
     74         setContentView(R.layout.activity_main);
     75 
     76         mImageView1 = (ImageView) findViewById(R.id.img1);
     77         mSearchBtn = (Button) findViewById(R.id.searchBtn);
     78         mAddFaceBtn = (Button)findViewById(R.id.addFaceBtn);
     79         mResultText = (TextView) findViewById(R.id.resultBtn);
     80         mAddResultText = (TextView)findViewById(R.id.addRresultTV);
     81         uidEidtText = (EditText)findViewById(R.id.uidEt);
     82         if(TextUtils.isEmpty(key) || TextUtils.isEmpty(secret)){
     83             AlertDialog.Builder builder = new AlertDialog.Builder(this);
     84             builder.setMessage("please enter key and secret");
     85             builder.setTitle("");
     86             builder.show();
     87             return;
     88         }
     89         mImageView1.setOnClickListener(new View.OnClickListener() {
     90             @Override
     91             public void onClick(View v) {
     92                 startAlbumActivity(REQUEST_CODE1);
     93             }
     94         });
     95         mAddFaceBtn.setOnClickListener(new View.OnClickListener() {
     96             @Override
     97             public void onClick(View v) {
     98                 addFace();
     99             }
    100         });
    101         mSearchBtn.setOnClickListener(new View.OnClickListener() {
    102             @Override
    103             public void onClick(View v) {
    104                 startSearch();
    105             }
    106         });
    107     }
    108 
    109     private void addFace(){
    110         if ("".equals(mImgBase641) || mImgBase641 == null) {
    111             Toast.makeText(this, "请选择图片再添加", Toast.LENGTH_SHORT).show();
    112             return;
    113         }
    114         if(uidEidtText.getText().toString().equals("")){
    115             Toast.makeText(this,"请输入uid(名字)",Toast.LENGTH_SHORT).show();
    116             return;
    117         }
    118         mResultText.setText("人脸添加中...");
    119         new Thread(new Runnable() {
    120             @Override
    121             public void run() {
    122                 CommonOperate commonOperate = new CommonOperate(key, secret, false);
    123                 try{
    124                     //获取faceToken
    125                     Response response = commonOperate.detectBase64(mImgBase641, 0, null);
    126                     FaceOperate faceOperate = new FaceOperate(key,secret,false);
    127                     String faceToken = getFaceToken(response);
    128                     String uid = uidEidtText.getText().toString();
    129                     Log.i(TAG, "run: " + uid);
    130                     faceOperate.faceSetUserId(faceToken, uid);
    131                     faces.add(faceToken);
    132                     Message msg = new Message();
    133                     msg.what = i;
    134                     msg.obj = faceToken;
    135                     handler.sendMessage(msg);
    136                     //faceSet中添加faceToken
    137                     FaceSetOperate FaceSet = new FaceSetOperate(key, secret, false);
    138                     String faceTokens = creatFaceTokens(faces);
    139                     Response faceSet = FaceSet.addFaceByFaceToken(faceTokens, "469e42d27947506b44cee9a8dba2eb4f");
    140                     String result = new String(faceSet.getContent());
    141                     msg.what = j;
    142                     msg.obj = result;
    143                     handler.sendMessage(msg);
    144                 }catch (Exception e){
    145                     Log.i(TAG, "addFace: " +e.toString());
    146                 }
    147             }
    148         }).start();
    149     }
    150 
    151     private void startSearch() {
    152         if ("".equals(mImgBase641) || mImgBase641 == null) {
    153             Toast.makeText(this, "请选择图片再寻找", Toast.LENGTH_SHORT).show();
    154             return;
    155         }
    156         mResultText.setText("搜索比对中...");
    157         new Thread(new Runnable() {
    158             @Override
    159             public void run() {
    160                 Log.i(TAG, "run() called");
    161                 CommonOperate commonOperate = new CommonOperate(key, secret, false);
    162                 //获取faceToken
    163                 Response response = null;
    164                 try {
    165                     response = commonOperate.detectBase64(mImgBase641, 0, null);
    166                     String faceToken = getFaceToken(response);
    167                     Response searchByOuterId = commonOperate.searchByOuterId(faceToken, null, null, "test", 1);
    168                     Message msg = new Message();
    169                     msg.what = s;
    170                     String result = new String(searchByOuterId.getContent());
    171                     msg.obj = result;
    172                     handler.sendMessage(msg);
    173                 } catch (Exception e) {
    174                     e.printStackTrace();
    175                 }
    176             }
    177         }).start();
    178     }
    179 
    180     private void startAlbumActivity(int requestCode) {
    181         Intent intent = new Intent();
    182         intent.setType("image/*");
    183         intent.setAction(Intent.ACTION_GET_CONTENT);
    184         startActivityForResult(intent, requestCode);
    185     }
    186 
    187     @Override
    188     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    189         if (data == null)
    190             return;
    191         Uri uri = data.getData();
    192         Log.e("uri", uri.toString());
    193         ContentResolver cr = this.getContentResolver();
    194         Bitmap bitmap = null;
    195         try {
    196             bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri));
    197                 /* 将Bitmap设定到ImageView */
    198         } catch (FileNotFoundException e) {
    199             Log.e("Exception", e.getMessage(), e);
    200         }
    201         if (resultCode == RESULT_OK && requestCode == REQUEST_CODE1) {
    202             mImageView1.setImageBitmap(bitmap);
    203             mImgBase641 = bitmapToBase64(bitmap);
    204         }
    205         super.onActivityResult(requestCode, resultCode, data);
    206     }
    207 
    208     private String bitmapToBase64(Bitmap bitmap) {
    209         ByteArrayOutputStream bStream = new ByteArrayOutputStream();
    210         bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bStream);
    211         return Base64.encodeToString(bStream.toByteArray(), 0);
    212     }
    213 
    214     private String getFaceToken(Response response) throws JSONException {
    215         if(response.getStatus() != 200){
    216             return new String(response.getContent());
    217         }
    218         String res = new String(response.getContent());
    219         Log.e("response", res);
    220         JSONObject json = new JSONObject(res);
    221         String faceToken = json.optJSONArray("faces").optJSONObject(0).optString("face_token");
    222         return faceToken;
    223     }
    224 
    225     private String creatFaceTokens(ArrayList<String> faceTokens){
    226         if(faceTokens == null || faceTokens.size() == 0){
    227             return "";
    228         }
    229         StringBuffer face = new StringBuffer();
    230         for (int i = 0; i < faceTokens.size(); i++){
    231             if(i == 0){
    232                 face.append(faceTokens.get(i));
    233             }else{
    234                 face.append(",");
    235                 face.append(faceTokens.get(i));
    236             }
    237         }
    238         return face.toString();
    239     }
    240 }
    View Code

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

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

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

  • 相关阅读:
    博客园装修行动—我设计的新首页
    按作者名称查看评论
    [新功能]通过RSS阅读收藏夹
    [公告]首页小调整
    时间的格式化
    [公告]将读书心得区改成技术书评区
    [汇报]昨天晚上博客园的程序又出现了问题
    [公告]博客园已经成功迁移至新服务器
    [好消息]博客园乔迁新居
    [公告]博客园程序升级
  • 原文地址:https://www.cnblogs.com/jxust-jiege666/p/8595483.html
Copyright © 2011-2022 走看看