1. 程式人生 > >使用face++的API介面-人臉識別

使用face++的API介面-人臉識別

本文地址:http://blog.csdn.net/tiandixuanwuliang/article/details/78018687

本文將介紹如何使用face++的API介面實現人臉識別。

一、獲取face++的API支援

1.1face++官網:https://www.faceplusplus.com.cn/

1.2在face++官網上註冊賬號,填寫開發者資料,如下圖:


二、建立API Key和繫結Bundle ID

2.1在如下圖位置,點選API Key


2.2點選建立API key,按照要求填寫(選擇試用):


2.3繫結應用程式:


至此,我們的準備工作就做好了。我們將會使用API Key和API Secret。


三、建立Android工程

3.1建立Android專案。本文使用Fragment+Activity模式,Activity程式碼是簡單的fragment,如下

  1. package com.wllfengshu.boyandgirl;
  2. import android.annotation.SuppressLint;
  3. import android.app.Activity;
  4. import android.app.FragmentManager;
  5. import android.app.FragmentTransaction;
  6. import android.os.Bundle;
  7. import android.view.View;
  8. public class MainActivity extends Activity {
  9. private FragmentManager fm;
  10. private FragmentTransaction transaction;
  11. @SuppressLint("NewApi")
  12. @Override
  13. protected void onCreate(Bundle savedInstanceState) {
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.activity_main);
  16. fm = getFragmentManager();
  17. transaction = fm.beginTransaction();
  18. transaction.replace(R.id.ll_fregment, new FaceFragment());
  19. transaction.commit();
  20. }
  21. public void change(View v) {
  22. transaction = fm.beginTransaction();
  23. switch (v.getId()) {
  24. case R.id.ib_main_face:
  25. transaction.replace(R.id.ll_fregment, new FaceFragment());
  26. break;
  27. case R.id.ib_main_gesture:
  28. transaction.replace(R.id.ll_fregment, new GestureFragment());
  29. break;
  30. case R.id.ib_main_other:
  31. transaction.replace(R.id.ll_fregment, new OtherFragment());
  32. break;
  33. }
  34. transaction.commit();
  35. }
  36. }
3.2fragment程式碼如下:(其中封裝的函式會在下文中介紹)
  1. package com.wllfengshu.boyandgirl;
  2. import java.io.IOException;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import org.json.JSONException;
  7. import org.json.JSONObject;
  8. import android.annotation.SuppressLint;
  9. import android.app.Fragment;
  10. import android.content.Intent;
  11. import android.graphics.Bitmap;
  12. import android.graphics.BitmapFactory;
  13. import android.graphics.Paint;
  14. import android.os.Bundle;
  15. import android.os.Handler;
  16. import android.os.Message;
  17. import android.view.LayoutInflater;
  18. import android.view.View;
  19. import android.view.View.OnClickListener;
  20. import android.view.ViewGroup;
  21. import android.widget.Button;
  22. import android.widget.ImageView;
  23. import android.widget.TextView;
  24. import android.widget.Toast;
  25. import com.wllfengshu.util.Constant;
  26. import com.wllfengshu.util.DrawUtil;
  27. import com.wllfengshu.util.GifView;
  28. import com.wllfengshu.util.HttpUtils;
  29. import com.wllfengshu.util.ImageUtil;
  30. @SuppressLint({ "NewApi", "HandlerLeak" })
  31. public class FaceFragment extends Fragment implements OnClickListener {
  32. private ImageView iv_face;// 錕矯夥拷選錕斤拷錕酵計�
  33. private Button ib_face_enter;// 確錕斤拷錕斤拷鈕
  34. private Button ib_face_choice;// 選錕斤拷圖片錕斤拷鈕錕斤拷錕斤拷圖錕解)
  35. private TextView tv_face_gender;
  36. private TextView tv_face_age;
  37. private TextView tv_face_beauty;
  38. private Bitmap scalingPhoto;// 點陣圖
  39. private String gender;// 性別
  40. private int age;// 年齡
  41. private int beauty;// 顏值
  42. private Paint paint;// 畫筆工具
  43. private View view;
  44. private GifView gif;
  45. @Override
  46. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  47. Bundle savedInstanceState) {
  48. view = inflater.inflate(R.layout.fragment_face, container, false);
  49. iv_face = (ImageView) view.findViewById(R.id.iv_face);
  50. ib_face_enter = (Button) view.findViewById(R.id.ib_face_enter);
  51. ib_face_choice = (Button) view.findViewById(R.id.ib_face_choice);
  52. tv_face_gender = (TextView) view.findViewById(R.id.tv_face_gender);
  53. tv_face_age = (TextView) view.findViewById(R.id.tv_face_age);
  54. tv_face_beauty = (TextView) view.findViewById(R.id.tv_face_beauty);
  55. gif = (GifView) view.findViewById(R.id.gif);
  56. ib_face_enter.setOnClickListener(this);
  57. ib_face_choice.setOnClickListener(this);
  58. paint = new Paint();// 建立畫筆
  59. scalingPhoto = BitmapFactory.decodeResource(this.getResources(),
  60. R.drawable.defualt);
  61. return view;
  62. }
  63. @SuppressLint("HandlerLeak")
  64. private Handler handler = new Handler() {
  65. @Override
  66. public void handleMessage(Message msg) {
  67. String str = (String) msg.obj;
  68. System.out.println("*******face:" + str);
  69. if (str.equals("403") || str.equals("400") || str.equals("413")
  70. || str.equals("500")) {
  71. Toast.makeText(getActivity(), "Please Try Again",
  72. Toast.LENGTH_SHORT).show();
  73. } else {
  74. try {
  75. JSONObject resultJSON = new JSONObject(str);
  76. System.out.println(resultJSON.getString("faces") + "=====");
  77. if (resultJSON.getString("faces").equals("[]")) {
  78. Toast.makeText(getActivity(),
  79. "There is no face picture", Toast.LENGTH_SHORT)
  80. .show();
  81. } else {
  82. @SuppressWarnings("rawtypes")
  83. List res = DrawUtil.FacePrepareBitmap(resultJSON,
  84. scalingPhoto, paint, iv_face);
  85. gender = (String) res.get(0);
  86. age = (Integer) res.get(1);
  87. beauty = (Integer) res.get(2);
  88. System.out.println("------------" + gender + " " + age
  89. + " " + " " + beauty);
  90. tv_face_gender.setText("性別:"
  91. + ImageUtil.getFaceGender(gender));
  92. tv_face_age.setText("年齡:" + age);
  93. tv_face_beauty.setText("顏值:" + beauty);
  94. }
  95. } catch (JSONException e) {
  96. e.printStackTrace();
  97. }
  98. }
  99. gif.setVisibility(View.GONE);// 停止gif
  100. };
  101. };
  102. @Override
  103. public void onActivityResult(int requestCode, int resultCode, Intent data) {
  104. if (requestCode == 1) {
  105. // 錕矯夥拷選錕斤拷錕酵計拷錕斤拷錕斤拷錕斤拷荽錕斤拷錕絛ata錕斤拷
  106. if (data != null) {
  107. // 錕矯碉拷圖片錕斤拷路錕斤拷
  108. String photoPath = ImageUtil.getPhotoPath(getActivity(), data);
  109. // 錕斤拷錕斤拷
  110. scalingPhoto = ImageUtil.getScalingPhoto(photoPath);
  111. // 錕斤拷示圖片
  112. iv_face.setImageBitmap(scalingPhoto);
  113. }
  114. }
  115. super.onActivityResult(requestCode, resultCode, data);
  116. }
  117. @Override
  118. public void onClick(View v) {
  119. switch (v.getId()) {
  120. case R.id.ib_face_choice:
  121. // 錕斤拷圖錕斤拷
  122. Intent intent = new Intent();
  123. intent.setAction(Intent.ACTION_PICK);
  124. intent.setType("image/*");
  125. startActivityForResult(intent, 1);// 通錕斤拷氐錕斤拷蚩錕斤拷錕�
  126. break;
  127. case R.id.ib_face_enter:
  128. // 顯示載入動畫
  129. gif.setVisibility(View.VISIBLE);
  130. gif.setMovieResource(R.raw.red); // 設定背景gif圖片資源
  131. String base64ImageEncode = ImageUtil
  132. .getBase64ImageEncode(scalingPhoto);
  133. System.out.println(base64ImageEncode);
  134. // 錕斤拷裝錕斤拷錕斤拷錕斤拷錕斤拷錕斤拷錕�
  135. final Map<String, Object> map = new HashMap<String, Object>();
  136. map.put("api_key", Constant.API_KEY);
  137. map.put("api_secret", Constant.API_SECRET);
  138. map.put("return_attributes", "gender,age,beauty");
  139. map.put("image_base64", base64ImageEncode);
  140. // 錕斤拷錕斤拷錕斤拷錕斤拷錕斤拷錕斤拷
  141. new Thread(new Runnable() {
  142. @Override
  143. public void run() {
  144. try {
  145. String result = HttpUtils
  146. .post(Constant.URL_DETECT, map);
  147. Message message = new Message();
  148. message.obj = result;
  149. handler.sendMessage(message);
  150. } catch (IOException e) {
  151. e.printStackTrace();
  152. }
  153. }
  154. }).start();
  155. break;
  156. }
  157. }
  158. }
上面程式碼說明:fragment頁面中包含兩個按鈕,一個按鈕點選“開啟手機相簿”,一個按鈕點選“確認”。使用者點選確認後,開始把使用者選擇的人臉圖片通過POST請求方式傳送到face++伺服器,等待獲取人臉特徵的資料。
其中封裝的POST請求程式碼如下:
  1. public static String post(String url, Map<String, Object> args) throws IOException {
  2. URL host = new URL(url);
  3. HttpURLConnection connection = HttpURLConnection.class.cast(host.openConnection());
  4. connection.setRequestMethod("POST");
  5. connection.setDoOutput(true);
  6. connection.setDoInput(true);
  7. connection.setUseCaches(false);
  8. connection.setRequestProperty("Connection", "Keep-Alive");
  9. connection.setRequestProperty("Charsert", "UTF-8");
  10. DataOutputStream dos = new DataOutputStream(connection.getOutputStream());
  11. if (args != null) {
  12. for (Entry<String, Object> entry : args.entrySet()) {
  13. String key = entry.getKey();
  14. Object value = entry.getValue();
  15. if (value instanceof File) {
  16. value = new FileInputStream(File.class.cast(value));
  17. }
  18. if (value instanceof InputStream) {
  19. dos.write((key + "=").getBytes());
  20. InputStream is = InputStream.class.cast(value);
  21. byte[] data = new byte[is.available()];
  22. is.read(data);
  23. dos.write(URLEncoder.encode(Base64.encodeToString(data, data.length), "UTF-8").getBytes());
  24. is.close();
  25. } else {
  26. dos.write((key + "=" + URLEncoder.encode(String.valueOf(value), "UTF-8")).getBytes());
  27. }
  28. dos.write("&".getBytes());
  29. }
  30. }
  31. dos.flush();
  32. dos.close();
  33. int resultCode = connection.getResponseCode();
  34. StringBuilder response = new StringBuilder();
  35. if (resultCode == HttpURLConnection.HTTP_OK) {
  36. BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
  37. String line;
  38. while ((line = br.readLine()) != null) {
  39. response.append(line);
  40. }
  41. br.close();
  42. } else {
  43. response.append(resultCode);
  44. }
  45. return response.toString();
  46. }
本文采用把圖片轉換為base64格式進行傳輸,其程式碼如下:
  1. public static String getBase64ImageEncode(Bitmap myImage) {
  2. Bitmap bmSmall = Bitmap.createBitmap(myImage, 0, 0, myImage.getWidth(), myImage.getHeight());
  3. ByteArrayOutputStream stream = new ByteArrayOutputStream();
  4. bmSmall.compress(Bitmap.CompressFormat.JPEG, 100, stream);
  5. byte[] arrays = stream.toByteArray();
  6. // base64 encode
  7. byte[] encode = Base64.encode(arrays, Base64.DEFAULT);
  8. String base64Encode = new String(encode);
  9. return base64Encode;
  10. }
介面佈局檔案程式碼(activity_main.xml檔案):
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="@drawable/bg" >
  6. <LinearLayout
  7. android:id="@+id/ll_fregment"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent"
  10. android:orientation="vertical" >
  11. </LinearLayout>
  12. <LinearLayout
  13. android:layout_width="match_parent"
  14. android:layout_height="wrap_content"
  15. android:layout_alignParentBottom="true"
  16. android:orientation="horizontal" >
  17. <RadioGroup
  18. android:layout_width="match_parent"
  19. android:layout_height="50dp"
  20. android:orientation="horizontal" >
  21. <RadioButton
  22. android:id="@+id/ib_main_face"
  23. android:layout_width="match_parent"
  24. android:layout_height="match_parent"
  25. android:layout_weight="1"
  26. android:background="@drawable/rb_select"
  27. android:button="@null"
  28. android:checked="true"
  29. android:gravity="center"
  30. android:onClick="change"
  31. android:text="人臉識別" />
  32. <RadioButton
  33. android:id="@+id/ib_main_gesture"
  34. android:layout_width="match_parent"
  35. android:layout_height="match_parent"
  36. android:layout_weight="1"
  37. android:background="@drawable/rb_select"
  38. android:button="@null"
  39. android:gravity="center"
  40. android:onClick="change"
  41. android:text="手勢識別" />
  42. <RadioButton
  43. android:id="@+id/ib_main_other"
  44. android:layout_width="match_parent"
  45. android:layout_height="match_parent"
  46. android:layout_weight="1"
  47. android:background="@drawable/rb_select"
  48. android:button="@null"
  49. android:gravity="center"
  50. android:onClick="change"
  51. android:text="其他功能" />
  52. </RadioGroup>
  53. </LinearLayout>
  54. </RelativeLayout>
人臉識別介面程式碼:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent" >
  5. <TextView
  6. android:layout_width="match_parent"
  7. android:layout_height="wrap_content"
  8. android:gravity="center"
  9. android:text="人臉識別"
  10. android:textSize="20sp" />
  11. <ImageView
  12. android:id="@+id/iv_face"
  13. android:layout_width="200dp"
  14. android:layout_height="300dp"
  15. android:layout_alignParentTop="true"
  16. android:layout_centerHorizontal="true"
  17. android:contentDescription="人臉圖片"
  18. android:paddingTop="40dp"
  19. android:src="@drawable/defualt" />
  20. <LinearLayout
  21. android:id="@+id/ll_button"
  22. android:layout_width="match_parent"
  23. android:layout_height="wrap_content"
  24. android:layout_below="@id/iv_face"
  25. android:layout_marginLeft="10dp"
  26. android:layout_marginRight="10dp"
  27. android:gravity="center_horizontal"
  28. android:orientation="horizontal" >
  29. <Button
  30. android:id="@+id/ib_face_enter"
  31. android:layout_width="wrap_content"
  32. android:layout_height="wrap_content"
  33. android:background="@drawable/enter"
  34. android:text="確定" />
  35. <Button
  36. android:id="@+id/ib_face_choice"
  37. android:layout_width="wrap_content"
  38. android:layout_height="wrap_content"
  39. android:background="@drawable/choose"
  40. android:text="選擇圖片" />
  41. </LinearLayout>
  42. <LinearLayout
  43. android:layout_width="match_parent"
  44. android:layout_height="wrap_content"
  45. android:layout_alignParentBottom="true"
  46. android:layout_below="@id/ll_button"
  47. android:orientation="horizontal"
  48. android:paddingTop="20dp" >
  49. <TextView
  50. android:id="@+id/tv_face_gender"
  51. android:layout_width="wrap_content"
  52. android:layout_height="wrap_content"
  53. android:layout_weight="1"
  54. android:gravity="center"
  55. android:src="@drawable/ic_launcher"
  56. android:text="性別"
  57. android:textSize="20sp" />
  58. <TextView
  59. android:id="@+id/tv_face_age"
  60. android:layout_width="wrap_content"
  61. android:layout_height="wrap_content"
  62. android:layout_weight="1"
  63. android:gravity="center"
  64. android:src="@drawable/ic_launcher"
  65. android:text="年齡"
  66. android:textSize="20sp" />
  67. <TextView
  68. android:id="@+id/tv_face_beauty"
  69. android:layout_width="wrap_content"
  70. android:layout_height="wrap_content"
  71. android:layout_weight="1"
  72. android:gravity="center"
  73. android:src="@drawable/ic_launcher"
  74. android:text="顏值"
  75. android:textSize="20sp" />
  76. </LinearLayout>
  77. <com.wllfengshu.util.GifView
  78. android:id="@+id/gif"
  79. android:layout_width="200dp"
  80. android:layout_height="200dp"
  81. android:layout_centerHorizontal="true"
  82. android:layout_gravity="center_horizontal"
  83. android:layout_marginTop="60dp"
  84. android:enabled="false" />
  85. </RelativeLayout>

人臉識別介面:

本文還有一些其他的封裝函式,由於篇幅問題不一一貼上,請大家自行下載本文程式碼案例:
下載地址:http://download.csdn.net/download/tiandixuanwuliang/9984027