使用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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值