使用face++接口实现在Android设备上的人脸识别
来源:互联网 发布:被网络诈骗了怎么办 编辑:程序博客网 时间:2024/05/16 10:14
这几天公司事情不多,把前段时间的弄得一个小项目整理一下,之前曾经用opencv做过人脸识别的相关项目,说实话效果不好,这次用了一下face++的接口实现,比之前的效果好不少,而且也没什么难度,现在就整理一下代码,做个备份吧。
在真正使用之前需要到face++ 网站下载faceppsdk.jar文件,然后倒入eclipse中
以下是布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Bing_By_Fj" >
<Button
android:id="@+id/facedectbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Face++检测" />
<FrameLayout
android:id="@+id/bing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
</FrameLayout>
<TextView
android:id="@+id/smiliar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:textSize="25sp"
android:text="检测值" />
<ImageView
android:id="@+id/takepicture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:src="@drawable/light1_001" />
<TextView
android:id="@+id/information"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="信息"
android:textSize="25sp" />
</RelativeLayout>
首先需要初始化 HttpRequests mRequests;
mRequests=new HttpRequests(String apiKey,String apiSecret);
这里的apikey 和apisecret需要申请;
进入程序后初始化摄像头,并在surfaceview上预览,
mCamera = Camera.open(FindFrontCamera());
cameraLayout.addView(new cameraView(bFj, mCamera));
此处cameraView 为
class cameraView extends SurfaceView implements Callback{
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
public cameraView(Context context,Camera camera) {
super(context);
// TODO Auto-generated constructor stub
SurfaceHolder surfaceHolder;
mCamera=camera;
surfaceHolder=getHolder();
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceHolder.addCallback(this);
mSupportedPreviewSizes=mCamera.getParameters().getSupportedPreviewSizes();
}
@SuppressLint("NewApi")
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(holder.getSurface() == null) { return; }
mCamera.stopPreview();
camera_h=height;
camera_w=width;
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
mCamera.setParameters(parameters);
requestLayout();
try {
setCameraDisplayOrientation(bFj, cameraID, mCamera);
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
// mCamera.setFaceDetectionListener(new face_Dect());
// startFaceDetection();
} catch (Exception e) {
// TODO: handle exception
}
camera_h=mPreviewSize.height;
camera_w=mPreviewSize.width;
new Thread(face_recon).start();
}
private Size getOptimalPreviewSize(List<Size> sizes,
int width, int height) {
// TODO Auto-generated method stub
final double ASPECT_TOLERANCE = 0.2;
double targetRatio = (double) width / height;
if (sizes == null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = height;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// We purposely disregard child measurements because act as a
// wrapper to a SurfaceView that centers the camera preview instead
// of stretching it.
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}
}
@SuppressLint("NewApi")
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int cameraCount = Camera.getNumberOfCameras(); // get cameras number
Log.i(TAG, "摄像头数量:"+cameraCount);
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
if (cameraCount<2) {
angle=-result;
} else {
angle=result;
}
camera.setDisplayOrientation(result);
}
代码有点多,可以跳过,
之后点击按钮进行拍照,获取图片 并进行上传
拍照的不说,直接说上传,并得到faceid 等信息,以便下次比较使用
b2s(myface);
myface 是得到的图片
b2s定义如下
public void b2s(Bitmap mBitmap){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
float scale = Math.min(1,
Math.min(600f / mBitmap.getWidth(), 600f / mBitmap.getHeight()));
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
Bitmap imgSmall = Bitmap.createBitmap(mBitmap, 0, 0,
mBitmap.getWidth(), mBitmap.getHeight(), matrix, false);
imgSmall.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] array = stream.toByteArray();
JSONObject mString = null;
try {
mString=mRequests.detectionDetect(new PostParameters().setImg(array));
} catch (FaceppParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(TAG, "返回;"+mString);
try {
String cc=mString.getJSONArray("face").getJSONObject(0).getString("face_id");
sex=mString.getJSONArray("face").getJSONObject(0).getJSONObject("attribute")
.getJSONObject("gender").getString("value");
smiling=mString.getJSONArray("face").getJSONObject(0).getJSONObject("attribute")
.getJSONObject("smiling").getString("value");
race=mString.getJSONArray("face").getJSONObject(0).getJSONObject("attribute")
.getJSONObject("race").getString("value");
age=mString.getJSONArray("face").getJSONObject(0).getJSONObject("attribute")
.getJSONObject("age").getString("value");
Log.i(TAG, "人中;"+race);
Log.i(TAG, "性别:"+sex);
Log.i(TAG, "微笑:"+smiling);
Log.i(TAG, "年龄:"+age);
Log.i(TAG, "face_id;"+cc);
if (!firstLogin) {
face_id2=cc;
}else {
face_id1=cc;
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (firstLogin) {
progressDialog.dismiss();
}
}
为了能够长久使用,需要将人脸创建 person 并将person添加到创建的group中
setpersonname();
groupcreate();
get_id(face_id1, group_id, group_name, person_id, person_name);
/**
* 创建person
*/
public void setpersonname(){
JSONObject mJsonObject=null;
try {
mJsonObject=mRequests.personCreate(new PostParameters()
.setFaceId(face_id1).
setPersonName(username));
} catch (FaceppParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(TAG, "id返回:"+mJsonObject);
if (firstLogin) {
try {
person_name=mJsonObject.getString("person_name");
person_id=mJsonObject.getString("person_id");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(TAG, "person_name:"+person_name);
Log.i(TAG, "person_id:"+person_id);
}
}
/**
* 创建组
*/
public void groupcreate(){
JSONObject mJsonObject=null;
try {
mJsonObject=mRequests.groupCreate(new PostParameters()
.setGroupId(username)
.setPersonName(username));
} catch (FaceppParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(TAG, "组创建:"+mJsonObject);
if (firstLogin) {
try {
group_name=mJsonObject.getString("group_name");
group_id=mJsonObject.getString("group_id");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(TAG, "group_name:"+group_name);
Log.i(TAG, "group_id:"+group_id);
}
}
这样在第二次进入时,不需要在创建person等,只需要直接比较,
重复拍照上传,然后与之前的比较得到相似比,
方法如下:
/**
* 面部对比
*/
public void compare(){
JSONObject mJsonObject=null;
try {
mJsonObject=mRequests.recognitionCompare(new PostParameters()
.setFaceId1(face_id1).
setFaceId2(face_id2));
} catch (FaceppParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(TAG, "比较返回:"+mJsonObject);
try {
smilar=Double.valueOf(mJsonObject.getString("similarity"));
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
progressDialog.dismiss();
checkface=true;
}
第一次写博客,逻辑好混乱,就这样了。
大概流程就是这些,在附上源码。
http://download.csdn.net/detail/l_b_ing/6946379
- 使用face++接口实现在Android设备上的人脸识别
- 使用face++的API接口-人脸识别
- Android使用Face++架构包实现人脸识别
- Android移动开发-在Android项目里集成face++人脸识别的实现
- 在树莓派上实现face++人脸识别
- 使用face++的API接口-手势识别
- face++人脸识别接口实现原理(一)
- face++实现人脸识别
- face++实现人脸识别
- face ++ 实现人脸识别
- [PHP]如何使用Face++接口开发微信公共平台的人脸识别系统
- face++人脸识别接口调用
- php使用face++实现一个简单的人脸识别系统
- Face++在线接口在Android下的使用,以及简单的Demo实现(判断两张脸是否为同一个人)
- 稀疏表达的人脸识别(Robust Face)实现
- 【Android】测试Face++的人脸识别算法
- iOS Face++人脸识别SDK的使用
- 初识Face++在android上的应用
- android项目用到的公共类方法
- Android应用程序通过JNI调用驱动程序(友善Smart210)
- SRM 602 D2L3:BlackBoxDiv2,dp
- structs2中的拦截器检测用户是否登陆
- Android开源项目汇总
- 使用face++接口实现在Android设备上的人脸识别
- Android 使用ViewPager实现左右循环滑动图片
- Database 各种数据连接
- Activity四种启动模式的利用场景
- uinity Animator 和Animation的正播,捯播,暂停动画实现方法(测试)
- Tomcat定时任务
- setw空格与setfill填充以及width
- grunt中ejs-static配置
- MySQL的reset slave与reset slave all