Android人脸识别之显示性别与年龄(Face++)

首先需要导入第三方包,在文末源码下载项目里面的libs文件夹下,或者到Face++官网下载(开发者工具与SDK中)

进入Face++注册账号

审核通过后,进入自己的应用,复制APIKEY 和API SECRET

Constant.java:

package com.example.howold;

public class Constant {

	public static final String APP_KEY = "4f1b065b596540f5456805d4c2c2923a";
	public static final String APP_SECRET = "Oge3CHP33ASirgJfrulMth-3gcLzD7Ts";
}

获取手机相册的图片显示到Imageview上:

Intent intent = new Intent(Intent.ACTION_PICK);
			intent.setType("image/*");
			startActivityForResult(intent, PICK_CODE);

@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		if (requestCode == PICK_CODE) {
			if (data != null) {
				Uri uri = data.getData();
				Cursor cursor = getContentResolver().query(uri, null, null, null, null);
				cursor.moveToFirst();

				int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
				mCurrentPhotoStr = cursor.getString(index);
				cursor.close();

				resizePhoto();
				mPhoto.setImageBitmap(mBitmapPhoto);
				mTip.setText("Click Detect ==>");
			}
		}
		super.onActivityResult(requestCode, resultCode, data);
	}
private void resizePhoto() {
<span style="white-space:pre">		</span>// TODO Auto-generated method stub
<span style="white-space:pre">		</span>BitmapFactory.Options options = new BitmapFactory.Options();
<span style="white-space:pre">		</span>options.inJustDecodeBounds = true;


<span style="white-space:pre">		</span>BitmapFactory.decodeFile(mCurrentPhotoStr, options);


<span style="white-space:pre">		</span>double ratio = Math.max(options.outWidth * 1.0d / 1024f, options.outHeight * 1.0d / 1024f);
<span style="white-space:pre">		</span>options.inSampleSize = (int) Math.ceil(ratio);
<span style="white-space:pre">		</span>options.inJustDecodeBounds = false;


<span style="white-space:pre">		</span>mBitmapPhoto = BitmapFactory.decodeFile(mCurrentPhotoStr, options);
<span style="white-space:pre">	</span>}
mPhoto即自己的ImageView


建立一个工具类,实现Bitmap与Byte之间的转换

BitmapByteUtil.java:
package Utils;

import java.io.ByteArrayOutputStream;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class BitmapByteUtil {

	public Bitmap byteToBitmap(byte[] temp){
		if(temp != null){
			Bitmap bitmap = BitmapFactory.decodeByteArray(temp, 0, temp.length);
			return bitmap;
		}
		return null;
	}
	public byte[] bitmapToByte(Bitmap photo){
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		if(photo != null){
			photo.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
			return byteArrayOutputStream.toByteArray();
		}
		return null;
	}
}

建立一个FaceppDetect类去获取JsonObject数据:

package Utils;

import org.apache.http.HttpRequest;
import org.json.JSONObject;

import com.example.howold.Constant;
import com.facepp.error.FaceppParseException;
import com.facepp.http.HttpRequests;
import com.facepp.http.PostParameters;

import android.graphics.Bitmap;
import android.util.Log;

public class FaceppDetect {

	private BitmapByteUtil bitmapByteUtil = new BitmapByteUtil();
	public interface CallBack{
		void success(JSONObject result);
		void error(FaceppParseException exception);
	}
	
	public static void detect(final Bitmap bitmap,final CallBack callBack){
		new Thread(new Runnable() {
			public void run() {
				try {
					BitmapByteUtil bitmapByteUtil = new BitmapByteUtil();
					//request
					HttpRequests httpRequests = new HttpRequests(Constant.APP_KEY, Constant.APP_SECRET, true, true);
					
					Bitmap bmSmall = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight());
					PostParameters parameters = new PostParameters();
					parameters.setImg(bitmapByteUtil.bitmapToByte(bmSmall));
					JSONObject jsonObject = httpRequests.detectionDetect(parameters);
					
					Log.e("TAG", jsonObject.toString());
					if(callBack!=null){
						callBack.success(jsonObject);
					}
				} catch (FaceppParseException e) {
					e.printStackTrace();
					if(callBack!=null){
						callBack.error(e);
					}
				}
			}
		}).start();
	}
}

Log.e("TAG", jsonObject.toString());打印出的JsonObject信息,复制,百度在线jsonobject校验,黏贴,校验,可以很清晰的看到数据结构

{
    "face": [
        {
            "attribute": {
                "age": {
                    "range": 6,
                    "value": 20
                },
                "gender": {
                    "confidence": 92.9548,
                    "value": "Male"
                },
                "race": {
                    "confidence": 99.0418,
                    "value": "Asian"
                },
                "smiling": {
                    "value": 16.9204
                }
            },
            "face_id": "5f98aef06dcf058be342dd480e1547a9",
            "position": {
                "center": {
                    "x": 56.869369,
                    "y": 35.25
                },
                "eye_left": {
                    "x": 54.705856,
                    "y": 33.151167
                },
                "eye_right": {
                    "x": 59.143694,
                    "y": 33.264833
                },
                "height": 7.5,
                "mouth_left": {
                    "x": 54.477027,
                    "y": 37.124167
                },
                "mouth_right": {
                    "x": 58.912613,
                    "y": 37.184667
                },
                "nose": {
                    "x": 57.071622,
                    "y": 35.007333
                },
                "width": 10.135135
            },
            "tag": ""
        }
    ],
    "img_height": 1048,
    "img_id": "01f2a35154ec947179fc5190292daac8",
    "img_width": 776,
    "session_id": "58dc50e81cf84c638b642c69ad79f315",
    "url": null,
    "response_code": 200
}


public static void detect(final Bitmap bitmap,final CallBack callBack)

该方法中的bitmap即你需要识别的图片


定义一个CallBack接口,去处理接收JsonObject数据,成功执行success,失败则执行error

由于JsonObject数据接收是在线程里面,所以我们用Handler通知外面UI进行相关操作:

private Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case MSG_SUCCESS:
				mWaiting.setVisibility(View.GONE);
				JSONObject rs = (JSONObject) msg.obj;
				prepareResultBitmap(rs);
				mPhoto.setImageBitmap(mBitmapPhoto);
				break;
			case MSG_ERROR:
				mWaiting.setVisibility(View.GONE);
				String errorMsg = (String) msg.obj;
				if (TextUtils.isEmpty(errorMsg)) {
					mTip.setText("Error.");
				} else {
					mTip.setText(errorMsg);
				}
				break;
			}
		}
	};
FaceppDetect.detect(mBitmapPhoto, new FaceppDetect.CallBack() {

					@Override
					public void success(JSONObject result) {
						// TODO Auto-generated method stub
						Message msg = mHandler.obtainMessage(MSG_SUCCESS);
						msg.obj = result;
						msg.sendToTarget();
					}

					@Override
					public void error(FaceppParseException exception) {
						// TODO Auto-generated method stub
						Message msg = mHandler.obtainMessage(MSG_ERROR);
						msg.obj = exception.getErrorMessage();
						msg.sendToTarget();
					}
				});
private void prepareResultBitmap(JSONObject rs) {
<span style="white-space:pre">		</span>// TODO Auto-generated method stub
<span style="white-space:pre">		</span>Bitmap bitmap = Bitmap.createBitmap(mBitmapPhoto.getWidth(), mBitmapPhoto.getHeight(),
<span style="white-space:pre">				</span>mBitmapPhoto.getConfig());
<span style="white-space:pre">		</span>canvas = new Canvas(bitmap);
<span style="white-space:pre">		</span>canvas.drawBitmap(mBitmapPhoto, 0, 0, null);


<span style="white-space:pre">		</span>try {
<span style="white-space:pre">			</span>JSONArray faces = rs.getJSONArray("face");
<span style="white-space:pre">			</span>int faceCount = faces.length();
<span style="white-space:pre">			</span>mTip.setText("find " + faceCount);


<span style="white-space:pre">			</span>for (int i = 0; i < faceCount; i++) {
<span style="white-space:pre">				</span>// 拿到单独face对象
<span style="white-space:pre">				</span>JSONObject face = faces.getJSONObject(i);
<span style="white-space:pre">				</span>JSONObject positonObj = face.getJSONObject("position");
<span style="white-space:pre">				</span>// get face position
<span style="white-space:pre">				</span>float x = (float) positonObj.getJSONObject("center").getDouble("x");
<span style="white-space:pre">				</span>float y = (float) positonObj.getJSONObject("center").getDouble("y");
<span style="white-space:pre">				</span>float w = (float) positonObj.getDouble("width");
<span style="white-space:pre">				</span>float h = (float) positonObj.getDouble("height");


<span style="white-space:pre">				</span>x = x / 100 * bitmap.getWidth();
<span style="white-space:pre">				</span>y = y / 100 * bitmap.getHeight();
<span style="white-space:pre">				</span>w = w / 100 * bitmap.getWidth();
<span style="white-space:pre">				</span>h = h / 100 * bitmap.getHeight();


<span style="white-space:pre">				</span>mPaint.setColor(0xffffffff);
<span style="white-space:pre">				</span>mPaint.setStrokeWidth(3);
<span style="white-space:pre">				</span>// draw box
<span style="white-space:pre">				</span>canvas.drawLine(x - w / 2, y - h / 2, x - w / 2, y + h / 2, mPaint);// 左
<span style="white-space:pre">				</span>canvas.drawLine(x - w / 2, y + h / 2, x + w / 2, y + h / 2, mPaint);// 下
<span style="white-space:pre">				</span>canvas.drawLine(x + w / 2, y + h / 2, x + w / 2, y - h / 2, mPaint);// 右
<span style="white-space:pre">				</span>canvas.drawLine(x - w / 2, y - h / 2, x + w / 2, y - h / 2, mPaint);// 上


<span style="white-space:pre">				</span>// get age and gender
<span style="white-space:pre">				</span>int age = face.getJSONObject("attribute").getJSONObject("age").getInt("value");
<span style="white-space:pre">				</span>String gender = face.getJSONObject("attribute").getJSONObject("gender").getString("value");


<span style="white-space:pre">				</span>Bitmap ageBitmap = buildAgeBitmap(age, gender.equals("Male"));
<span style="white-space:pre">				</span>
<span style="white-space:pre">				</span>int ageWidth = ageBitmap.getWidth();
<span style="white-space:pre">				</span>int ageHeight = ageBitmap.getHeight();
<span style="white-space:pre">				</span>if(bitmap.getWidth()<=mPhoto.getWidth() && bitmap.getHeight()<=mPhoto.getHeight()){
<span style="white-space:pre">					</span>float ratio = Math.max(bitmap.getWidth() * 1.0f / mPhoto.getWidth(),
<span style="white-space:pre">							</span>bitmap.getHeight() * 1.0f / mPhoto.getHeight());


<span style="white-space:pre">					</span>ageBitmap = Bitmap.createScaledBitmap(ageBitmap, (int) (ageWidth * ratio),
<span style="white-space:pre">							</span>(int) (ageHeight * ratio), false);
<span style="white-space:pre">					</span>canvas.drawBitmap(ageBitmap, x - ageBitmap.getWidth() / 2, y - h / 2 - ageBitmap.getHeight(), null);
<span style="white-space:pre">				</span>}
<span style="white-space:pre">					</span>mBitmapPhoto = bitmap;
<span style="white-space:pre">			</span>}
<span style="white-space:pre">		</span>} catch (JSONException e) {
<span style="white-space:pre">			</span>// TODO Auto-generated catch block
<span style="white-space:pre">			</span>e.printStackTrace();
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>};


<span style="white-space:pre">	</span>private Bitmap buildAgeBitmap(int age, boolean isMale) {
<span style="white-space:pre">		</span>// TODO Auto-generated method stub
<span style="white-space:pre">		</span>TextView tv = (TextView) mWaiting.findViewById(R.id.id_age_and_gender);
<span style="white-space:pre">		</span>tv.setText(age + "");
<span style="white-space:pre">		</span>if (isMale) {
<span style="white-space:pre">			</span>tv.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.male), null, null, null);
<span style="white-space:pre">		</span>} else {
<span style="white-space:pre">			</span>tv.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.female), null, null, null);
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>tv.setDrawingCacheEnabled(true);
<span style="white-space:pre">		</span>Bitmap bitmap = Bitmap.createBitmap(tv.getDrawingCache());
<span style="white-space:pre">		</span>tv.destroyDrawingCache();
<span style="white-space:pre">		</span>return bitmap;
<span style="white-space:pre">	</span>}


需要源码的留下你的邮箱(源码下载



  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值