本文地址: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 map = new HashMap();
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 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 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文件):
人脸识别界面代码:
人脸识别界面:
本文还有一些其他的封装函数,由于篇幅问题不一一粘贴,请大家自行下载本文代码案例:
下载地址:http://download.csdn.net/download/tiandixuanwuliang/9984027