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

1 0
原创粉丝点击