赞
踩
本文地址: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,如下
- package com.wllfengshu.boyandgirl;
-
- import android.annotation.SuppressLint;
- import android.app.Activity;
- import android.app.FragmentManager;
- import android.app.FragmentTransaction;
- import android.os.Bundle;
- import android.view.View;
-
- public class MainActivity extends Activity {
-
- private FragmentManager fm;
- private FragmentTransaction transaction;
-
- @SuppressLint("NewApi")
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- fm = getFragmentManager();
- transaction = fm.beginTransaction();
- transaction.replace(R.id.ll_fregment, new FaceFragment());
- transaction.commit();
-
- }
-
- public void change(View v) {
- transaction = fm.beginTransaction();
- switch (v.getId()) {
- case R.id.ib_main_face:
- transaction.replace(R.id.ll_fregment, new FaceFragment());
- break;
- case R.id.ib_main_gesture:
- transaction.replace(R.id.ll_fregment, new GestureFragment());
- break;
- case R.id.ib_main_other:
- transaction.replace(R.id.ll_fregment, new OtherFragment());
- break;
- }
- transaction.commit();
- }
- }
3.2fragment代码如下:(其中封装的函数会在下文中介绍)
- package com.wllfengshu.boyandgirl;
-
- import java.io.IOException;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
-
- import org.json.JSONException;
- import org.json.JSONObject;
-
- import android.annotation.SuppressLint;
- import android.app.Fragment;
- import android.content.Intent;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Paint;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.ViewGroup;
- import android.widget.Button;
- import android.widget.ImageView;
- import android.widget.TextView;
- import android.widget.Toast;
-
- import com.wllfengshu.util.Constant;
- import com.wllfengshu.util.DrawUtil;
- import com.wllfengshu.util.GifView;
- import com.wllfengshu.util.HttpUtils;
- import com.wllfengshu.util.ImageUtil;
-
-
- @SuppressLint({ "NewApi", "HandlerLeak" })
- public class FaceFragment extends Fragment implements OnClickListener {
-
- private ImageView iv_face;// 锟矫伙拷选锟斤拷锟酵计�
- private Button ib_face_enter;// 确锟斤拷锟斤拷钮
- private Button ib_face_choice;// 选锟斤拷图片锟斤拷钮锟斤拷锟斤拷图锟解)
-
- private TextView tv_face_gender;
- private TextView tv_face_age;
- private TextView tv_face_beauty;
-
- private Bitmap scalingPhoto;// 位图
-
- private String gender;// 性别
- private int age;// 年龄
- private int beauty;// 颜值
-
- private Paint paint;// 画笔工具
- private View view;
- private GifView gif;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- view = inflater.inflate(R.layout.fragment_face, container, false);
-
- iv_face = (ImageView) view.findViewById(R.id.iv_face);
- ib_face_enter = (Button) view.findViewById(R.id.ib_face_enter);
- ib_face_choice = (Button) view.findViewById(R.id.ib_face_choice);
-
- tv_face_gender = (TextView) view.findViewById(R.id.tv_face_gender);
- tv_face_age = (TextView) view.findViewById(R.id.tv_face_age);
- tv_face_beauty = (TextView) view.findViewById(R.id.tv_face_beauty);
-
- gif = (GifView) view.findViewById(R.id.gif);
-
- ib_face_enter.setOnClickListener(this);
- ib_face_choice.setOnClickListener(this);
-
- paint = new Paint();// 创建画笔
- scalingPhoto = BitmapFactory.decodeResource(this.getResources(),
- R.drawable.defualt);
-
- return view;
- }
-
- @SuppressLint("HandlerLeak")
- private Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- String str = (String) msg.obj;
- System.out.println("*******face:" + str);
- if (str.equals("403") || str.equals("400") || str.equals("413")
- || str.equals("500")) {
- Toast.makeText(getActivity(), "Please Try Again",
- Toast.LENGTH_SHORT).show();
-
- } else {
- try {
- JSONObject resultJSON = new JSONObject(str);
- System.out.println(resultJSON.getString("faces") + "=====");
- if (resultJSON.getString("faces").equals("[]")) {
- Toast.makeText(getActivity(),
- "There is no face picture", Toast.LENGTH_SHORT)
- .show();
-
- } else {
- @SuppressWarnings("rawtypes")
- List res = DrawUtil.FacePrepareBitmap(resultJSON,
- scalingPhoto, paint, iv_face);
- gender = (String) res.get(0);
- age = (Integer) res.get(1);
- beauty = (Integer) res.get(2);
-
- System.out.println("------------" + gender + " " + age
- + " " + " " + beauty);
-
- tv_face_gender.setText("性别:"
- + ImageUtil.getFaceGender(gender));
- tv_face_age.setText("年龄:" + age);
- tv_face_beauty.setText("颜值:" + beauty);
- }
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
- gif.setVisibility(View.GONE);// 停止gif
- };
- };
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == 1) {
- // 锟矫伙拷选锟斤拷锟酵计拷锟斤拷锟斤拷锟斤拷荽锟斤拷锟絛ata锟斤拷
- if (data != null) {
- // 锟矫碉拷图片锟斤拷路锟斤拷
- String photoPath = ImageUtil.getPhotoPath(getActivity(), data);
- // 锟斤拷锟斤拷
- scalingPhoto = ImageUtil.getScalingPhoto(photoPath);
- // 锟斤拷示图片
- iv_face.setImageBitmap(scalingPhoto);
- }
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.ib_face_choice:
- // 锟斤拷图锟斤拷
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_PICK);
- intent.setType("image/*");
- startActivityForResult(intent, 1);// 通锟斤拷氐锟斤拷蚩锟斤拷锟�
- break;
- case R.id.ib_face_enter:
- // 显示加载动画
- gif.setVisibility(View.VISIBLE);
- gif.setMovieResource(R.raw.red); // 设置背景gif图片资源
-
-
- String base64ImageEncode = ImageUtil
- .getBase64ImageEncode(scalingPhoto);
- System.out.println(base64ImageEncode);
- // 锟斤拷装锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟�
- final Map<String, Object> map = new HashMap<String, Object>();
- map.put("api_key", Constant.API_KEY);
- map.put("api_secret", Constant.API_SECRET);
- map.put("return_attributes", "gender,age,beauty");
- map.put("image_base64", base64ImageEncode);
-
- // 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- String result = HttpUtils
- .post(Constant.URL_DETECT, map);
- Message message = new Message();
- message.obj = result;
- handler.sendMessage(message);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }).start();
- break;
- }
- }
- }
上面代码说明:fragment页面中包含两个按钮,一个按钮点击“打开手机图库”,一个按钮点击“确认”。用户点击确认后,开始把用户选择的人脸图片通过POST请求方式发送到face++服务器,等待获取人脸特征的数据。
- public static String post(String url, Map<String, Object> args) throws IOException {
-
- URL host = new URL(url);
- HttpURLConnection connection = HttpURLConnection.class.cast(host.openConnection());
-
- connection.setRequestMethod("POST");
-
- connection.setDoOutput(true);
- connection.setDoInput(true);
-
- connection.setUseCaches(false);
- connection.setRequestProperty("Connection", "Keep-Alive");
- connection.setRequestProperty("Charsert", "UTF-8");
- DataOutputStream dos = new DataOutputStream(connection.getOutputStream());
-
-
- if (args != null) {
- for (Entry<String, Object> entry : args.entrySet()) {
- String key = entry.getKey();
- Object value = entry.getValue();
-
- if (value instanceof File) {
- value = new FileInputStream(File.class.cast(value));
- }
-
- if (value instanceof InputStream) {
- dos.write((key + "=").getBytes());
- InputStream is = InputStream.class.cast(value);
- byte[] data = new byte[is.available()];
- is.read(data);
- dos.write(URLEncoder.encode(Base64.encodeToString(data, data.length), "UTF-8").getBytes());
-
- is.close();
- } else {
- dos.write((key + "=" + URLEncoder.encode(String.valueOf(value), "UTF-8")).getBytes());
- }
-
- dos.write("&".getBytes());
- }
- }
-
- dos.flush();
- dos.close();
- int resultCode = connection.getResponseCode();
- StringBuilder response = new StringBuilder();
- if (resultCode == HttpURLConnection.HTTP_OK) {
- BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
- String line;
- while ((line = br.readLine()) != null) {
- response.append(line);
- }
-
- br.close();
- } else {
- response.append(resultCode);
- }
- return response.toString();
- }
本文采用把图片转换为base64格式进行传输,其代码如下:
- public static String getBase64ImageEncode(Bitmap myImage) {
- Bitmap bmSmall = Bitmap.createBitmap(myImage, 0, 0, myImage.getWidth(), myImage.getHeight());
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- bmSmall.compress(Bitmap.CompressFormat.JPEG, 100, stream);
- byte[] arrays = stream.toByteArray();
- // base64 encode
- byte[] encode = Base64.encode(arrays, Base64.DEFAULT);
- String base64Encode = new String(encode);
- return base64Encode;
- }
界面布局文件代码(activity_main.xml文件):
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/bg" >
- <LinearLayout
- android:id="@+id/ll_fregment"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- </LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:orientation="horizontal" >
- <RadioGroup
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:orientation="horizontal" >
- <RadioButton
- android:id="@+id/ib_main_face"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:background="@drawable/rb_select"
- android:button="@null"
- android:checked="true"
- android:gravity="center"
- android:onClick="change"
- android:text="人脸识别" />
- <RadioButton
- android:id="@+id/ib_main_gesture"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:background="@drawable/rb_select"
- android:button="@null"
- android:gravity="center"
- android:onClick="change"
- android:text="手势识别" />
- <RadioButton
- android:id="@+id/ib_main_other"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:background="@drawable/rb_select"
- android:button="@null"
- android:gravity="center"
- android:onClick="change"
- android:text="其他功能" />
-
- </RadioGroup>
- </LinearLayout>
-
- </RelativeLayout>
人脸识别界面代码:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:text="人脸识别"
- android:textSize="20sp" />
- <ImageView
- android:id="@+id/iv_face"
- android:layout_width="200dp"
- android:layout_height="300dp"
- android:layout_alignParentTop="true"
- android:layout_centerHorizontal="true"
- android:contentDescription="人脸图片"
- android:paddingTop="40dp"
- android:src="@drawable/defualt" />
- <LinearLayout
- android:id="@+id/ll_button"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/iv_face"
- android:layout_marginLeft="10dp"
- android:layout_marginRight="10dp"
- android:gravity="center_horizontal"
- android:orientation="horizontal" >
- <Button
- android:id="@+id/ib_face_enter"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/enter"
- android:text="确定" />
- <Button
- android:id="@+id/ib_face_choice"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/choose"
- android:text="选择图片" />
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:layout_below="@id/ll_button"
- android:orientation="horizontal"
- android:paddingTop="20dp" >
- <TextView
- android:id="@+id/tv_face_gender"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:gravity="center"
- android:src="@drawable/ic_launcher"
- android:text="性别"
- android:textSize="20sp" />
- <TextView
- android:id="@+id/tv_face_age"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:gravity="center"
- android:src="@drawable/ic_launcher"
- android:text="年龄"
- android:textSize="20sp" />
- <TextView
- android:id="@+id/tv_face_beauty"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:gravity="center"
- android:src="@drawable/ic_launcher"
- android:text="颜值"
- android:textSize="20sp" />
- </LinearLayout>
- <com.wllfengshu.util.GifView
- android:id="@+id/gif"
- android:layout_width="200dp"
- android:layout_height="200dp"
- android:layout_centerHorizontal="true"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="60dp"
- android:enabled="false" />
- </RelativeLayout>
人脸识别界面:
本文还有一些其他的封装函数,由于篇幅问题不一一粘贴,请大家自行下载本文代码案例:
下载地址:http://download.csdn.net/download/tiandixuanwuliang/9984027
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。