人臉識別1:n對比 (二)

  本項目採用了百度AI 人臉識別 第三方接口,實現了自選本地手機相冊圖片上傳人臉(faceSet中添加人臉) 和 自選本地手機相冊圖片尋找出集合中類似度最高的一個face,可返回比對類似度、位置等信息。 html

目前百度向我的開發者提供了免費人臉識別接口,QPS限制爲2,企業認證後併發數可增至 5,我的測試仍是沒問題的。java

 

項目具體步驟以下:android

一 、所需權限算法

    <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"/>

2、第三方app id app keyapi

項目採用了百度AI 第三方接口,可自行註冊獲取緩存

3、添加依賴和sdk服務器

 

  1. http 工具類
      View Code

     

  2. Base64 工具類
      View Code

     

  以上是實現的Base64的加密算法,使用自帶 Base64.encodeToString(); 方法也能夠。併發

  Base64原理可參考這篇博文:http://www.cnblogs.com/jxust-jiege666/p/8590116.htmlapp

4、獲取tokenide

主要代碼:

  View Code

 

注意:access_token的有效期爲30天,切記須要每30天進行按期更換,或者每次請求都拉取新token;

5、添加人臉

  在1:n 對比搜索前,首先要向建立的face組內添加face (另外百度也提供了後臺添加加人臉,可登陸控制檯建立組和添加人臉),主要代碼以下:

 1 public static String identify(byte[] imgData,byte[] imgData2,String groupid,String accessToken) {
 2         // 請求url
 3         String url = "https://aip.baidubce.com/rest/2.0/face/v2/identify";
 4         try {
 5             // 本地文件路徑
 6             String imgStr = Base64Util.encode(imgData);
 7             String imgParam = URLEncoder.encode(imgStr, "UTF-8");
 8 
 9             String imgStr2 = Base64Util.encode(imgData2);
10             String imgParam2 = URLEncoder.encode(imgStr2, "UTF-8");
11 
12             String param = "group_id=" + groupid + "&user_top_num=" + "1" + "&face_top_num=" + "1" + "&images=" + imgParam + "," + imgParam2;
13 
14             // 注意這裏僅爲了簡化編碼每一次請求都去獲取access_token,線上環境access_token有過時時間, 客戶端可自行緩存,過時後從新獲取。
15 
16             String result = HttpUtil.post(url, accessToken, param);
17             System.out.println(result);
18             return result;
19         } catch (Exception e) {
20             e.printStackTrace();
21         }
22         return null;
23     }
24 }
View Code

其中groupid是你以前建立的組的id,user_top_num 是要返回類似度最高的人的個數,face_top_num是返回類似度最高人的face個數。一我的能夠添加多個face,該項目爲每一個人添加了兩個face。

6、尋找人臉

主要代碼:

 1 /**
 2  * 人臉查找——識別
 3  */
 4 public class Identify {
 5 
 6     /**
 7      * 重要提示代碼中所需工具類
 8      * FileUtil,Base64Util,HttpUtil,GsonUtils請從
 9      * https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
10      * https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
11      * https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
12      * https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
13      * 下載
14      */
15     public static String identify(byte[] imgData,byte[] imgData2,String groupid,String accessToken) {
16         // 請求url
17         String url = "https://aip.baidubce.com/rest/2.0/face/v2/identify";
18         try {
19      
20             String imgStr = Base64Util.encode(imgData);
21             String imgParam = URLEncoder.encode(imgStr, "UTF-8");
22 
23             String imgStr2 = Base64Util.encode(imgData2);
24             String imgParam2 = URLEncoder.encode(imgStr2, "UTF-8");
25 
26             String param = "group_id=" + groupid + "&user_top_num=" + "1" + "&face_top_num=" + "1" + "&images=" + imgParam + "," + imgParam2;
27 
28             // 注意這裏僅爲了簡化編碼每一次請求都去獲取access_token,線上環境access_token有過時時間, 客戶端可自行緩存,過時後從新獲取。
29 
30             String result = HttpUtil.post(url, accessToken, param);
31             System.out.println(result);
32             return result;
33         } catch (Exception e) {
34             e.printStackTrace();
35         }
36         return null;
37     }
38 }
View Code

7、頁面activity

主要代碼:

  1 import android.content.ContentResolver;
  2 import android.content.Intent;
  3 import android.graphics.Bitmap;
  4 import android.graphics.BitmapFactory;
  5 import android.net.Uri;
  6 import android.os.Bundle;
  7 import android.os.Handler;
  8 import android.os.Message;
  9 import android.support.v7.app.AlertDialog;
 10 import android.support.v7.app.AppCompatActivity;
 11 import android.text.TextUtils;
 12 import android.util.Log;
 13 import android.view.View;
 14 import android.widget.Button;
 15 import android.widget.EditText;
 16 import android.widget.ImageView;
 17 import android.widget.TextView;
 18 import android.widget.Toast;
 19 
 20 import com.example.lifen.baidufacesearchdemo.utils.AuthService;
 21 import com.example.lifen.baidufacesearchdemo.utils.Base64Util;
 22 import com.example.lifen.baidufacesearchdemo.utils.FaceAdd;
 23 import com.example.lifen.baidufacesearchdemo.utils.Identify;
 24 
 25 import java.io.ByteArrayOutputStream;
 26 import java.io.FileNotFoundException;
 27 
 28 /**
 29  * 人臉尋找 fase集合中尋找最類似(1 或 多)的face
 30  *
 31  * @author LiFen
 32  */
 33 public class MainActivity extends AppCompatActivity {
 34     private static final String TAG = "MainActivity";
 35     private static final int REQUEST_CODE1 = 11;
 36     ImageView mImageView1;
 37     Button mSearchBtn;
 38     private Button mAddFaceBtn;
 39     TextView mResultText;
 40     private TextView mAddResultText;
 41     private byte[] mImg1;
 42     private EditText uidEidtText;
 43     private EditText mInforEidtText;
 44     String key = "";//api_key
 45     String secret ="";//api_secret
 46     private final static int i = 100;
 47     private final static int j = 200;
 48     private final static int s = 300;
 49     private Handler handler = new Handler(){
 50         @Override
 51         public void handleMessage(Message msg) {
 52             if(msg.what == i){
 53                 mAddResultText.setText((String)msg.obj);
 54             }
 55             if(msg.what == j){
 56                 mAddResultText.append((String)msg.obj);
 57             }
 58             if(msg.what == s){
 59                 mResultText.setText((String)msg.obj);
 60             }
 61         }
 62     };
 63 
 64     @Override
 65     protected void onCreate(Bundle savedInstanceState) {
 66         super.onCreate(savedInstanceState);
 67         setContentView(R.layout.activity_main);
 68 
 69         mImageView1 = (ImageView) findViewById(R.id.img1);
 70         mSearchBtn = (Button) findViewById(R.id.searchBtn);
 71         mAddFaceBtn = (Button)findViewById(R.id.addFaceBtn);
 72         mResultText = (TextView) findViewById(R.id.resultBtn);
 73         mAddResultText = (TextView)findViewById(R.id.addRresultTV);
 74         uidEidtText = (EditText)findViewById(R.id.uidEt);
 75         mInforEidtText = (EditText)findViewById(R.id.inforEt);
 76         if(TextUtils.isEmpty(key) || TextUtils.isEmpty(secret)){
 77             AlertDialog.Builder builder = new AlertDialog.Builder(this);
 78             builder.setMessage("please enter key and secret");
 79             builder.setTitle("");
 80             builder.show();
 81             return;
 82         }
 83         mImageView1.setOnClickListener(new View.OnClickListener() {
 84             @Override
 85             public void onClick(View v) {
 86                 startAlbumActivity(REQUEST_CODE1);
 87             }
 88         });
 89         mAddFaceBtn.setOnClickListener(new View.OnClickListener() {
 90             @Override
 91             public void onClick(View v) {
 92                 addFace();
 93             }
 94         });
 95         mSearchBtn.setOnClickListener(new View.OnClickListener() {
 96             @Override
 97             public void onClick(View v) {
 98                 startSearch();
 99             }
100         });
101     }
102 
103     private void addFace(){
104         if ("".equals(mImg1) || mImg1 == null) {
105             Toast.makeText(this, "請選擇圖片再添加", Toast.LENGTH_SHORT).show();
106             return;
107         }
108         if(uidEidtText.getText().toString().equals("")){
109             Toast.makeText(this,"請輸入uid(名字)",Toast.LENGTH_SHORT).show();
110             return;
111         }
112         mAddResultText.setText("人臉添加中...");
113         new Thread(new Runnable() {
114             @Override
115             public void run() {
116                 String accessToken = AuthService.getAuth(key, secret);
117                 Log.i(TAG, "accessToken:" + accessToken);
118                 Message msg1 = new Message();
119                 msg1.what = i;
120                 msg1.obj = accessToken;
121                 handler.sendMessage(msg1);
122 
123                 String uid = uidEidtText.getText().toString();
124                 String infor = mInforEidtText.getText().toString();
125                 String encode = Base64Util.encode(infor.getBytes());
126                 Log.i(TAG, "infor: " + encode);
127                 /*String inforUtf = new String(Base64.decode(encode, Base64.DEFAULT));
128                 Log.i(TAG, "infor: " + inforUtf);*/
129                 String add = FaceAdd.add(mImg1, mImg1, uid,encode,"test",accessToken);
130                 Log.i(TAG, "addFace: " + add);
131                 Message msg2 = new Message();
132                 msg2.what = j;
133                 msg2.obj = add;
134                 handler.sendMessage(msg2);
135             }
136         }).start();
137     }
138 
139     private void startSearch() {
140         if ("".equals(mImg1) || mImg1 == null) {
141             Toast.makeText(this, "請選擇圖片再尋找", Toast.LENGTH_SHORT).show();
142             return;
143         }
144         mResultText.setText("搜索比對中...");
145         new Thread(new Runnable() {
146             @Override
147             public void run() {
148                 String accessToken = AuthService.getAuth(key, secret);
149                 Log.i(TAG, "accessToken:" + accessToken);
150                 String result = Identify.identify(mImg1, mImg1, "test", accessToken);
151                 Log.i(TAG, "result" + result);
152                 Message msg3 = new Message();
153                 msg3.what = s;
154                 msg3.obj = result;
155                 handler.sendMessage(msg3);
156             }
157         }).start();
158     }
159 
160     private void startAlbumActivity(int requestCode) {
161         Intent intent = new Intent();
162         intent.setType("image/*");
163         intent.setAction(Intent.ACTION_GET_CONTENT);
164         startActivityForResult(intent, requestCode);
165     }
166 
167     @Override
168     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
169         if (data == null)
170             return;
171         Uri uri = data.getData();
172         Log.e("uri", uri.toString());
173         ContentResolver cr = this.getContentResolver();
174         Bitmap bitmap = null;
175         try {
176             bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri));
177                 /* 將Bitmap設定到ImageView */
178         } catch (FileNotFoundException e) {
179             Log.e("Exception", e.getMessage(), e);
180         }
181         if (resultCode == RESULT_OK && requestCode == REQUEST_CODE1) {
182             mImageView1.setImageBitmap(bitmap);
183             ByteArrayOutputStream baos = new ByteArrayOutputStream();
184             bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
185             byte[] datas = baos.toByteArray();
186             mImg1 = datas;
187         }
188         super.onActivityResult(requestCode, resultCode, data);
189     }
190 }
View Code

8、佈局文件

1:n 尋找

頁面包含:

  ① ImageView 點擊ImageView 可跳轉手機相冊,選擇要使用的圖片。

  ② TextView1  faceSet添加face 結果再次顯示

  ③ EditText 設定face 的user_uid

  ④ button1 添加人臉按鈕

  ⑤ button2 尋找類似度最高人臉按鈕

  ⑥ TextView2 尋找結果展現view

 faceSet 中添加 face過程:

  1. 點擊imageView 選取圖片

  2. 輸入uid

  3. 添加face關聯的信息(這裏我Base64編碼後上傳的服務器,使用時可自行解碼)

  4. 點擊添加按鈕添加

 尋找類似度最高face過程:

  1.點擊imageView 選取圖片

  2. 點擊尋找按鈕

 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.baidufacesearchdemo.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="textCapCharacters" />
54 
55         <EditText
56             android:id="@+id/inforEt"
57             android:layout_width="match_parent"
58             android:layout_height="wrap_content"
59             android:ems="10"
60             android:hint="人臉關聯的其餘信息"
61             android:inputType="textPersonName" />
62 
63         <Button
64             android:id="@+id/addFaceBtn"
65             android:layout_width="match_parent"
66             android:layout_height="wrap_content"
67             android:text="添加" />
68 
69         <Button
70             android:id="@+id/searchBtn"
71             android:layout_width="match_parent"
72             android:layout_height="wrap_content"
73             android:layout_marginTop="@dimen/activity_horizontal_margin"
74             android:text="尋找" />
75 
76         <TextView
77             android:id="@+id/resultBtn"
78             android:layout_width="match_parent"
79             android:layout_height="wrap_content"
80             android:layout_marginTop="@dimen/activity_horizontal_margin"
81             android:background="#eeeeee"
82             android:padding="6dp"
83             android:layout_weight="2.94" />
84 
85     </LinearLayout>
86 </ScrollView>
View Code

 

 項目地址:https://download.csdn.net/download/qq_36726507/10295388

相關文章
相關標籤/搜索