android项目实战-人脸识别接口应用

android项目实战-人脸识别接口应用

      • 1.face++接口:
      • 2.源码:
      • 3.效果:
      • 4.App下载:
      • 5.代码解读:
        • FaceUtils.java
        • FaceAdapter.java
        • ImageResource.java
        • MainActivity.java
        • DetectActivity.java
        • BeautyActivity.java
        • DetailActivity.java
        • 其他

1.face++接口:

https://www.faceplusplus.com.cn/

2.源码:

https://gitee.com/zouchengxin/analyze_face

3.效果:

http://39.106.207.193:8080/analyze_face.mp4

4.App下载:

https://gitee.com/zouchengxin/analyze_face/blob/master/app/release/app-release.apk

5.代码解读:

FaceUtils.java

主要用来调用face++ Detect和Beautify接口并与DetectActivity和BeautyActivity通讯

public class FaceUtils {
   private String TAG="FaceUtils";
   private String api_key="_XkXB2jly_0ZteVlGNxI8cT6S8XE4Gnj";
   private String api_secret="guR94t2Pwg_0DKNTyt3QPe7iAQBuCtpa";
   private FacePPApi faceApi;

   public FaceUtils(){
       faceApi=new FacePPApi(api_key,api_secret);
   }

   //传入图片进行人脸检测和人脸分析
   public void detect_face(final AppCompatActivity activity, byte[] img){
       Map<String,String> map=new HashMap<>();
       map.put("return_landmark","1");
       map.put("return_attributes","gender,age,smiling,headpose,facequality,blur,eyestatus,emotion,ethnicity,beauty,mouthstatus,eyegaze,skinstatus");
       faceApi.detect(map,img,new IFacePPCallBack<DetectResponse>() {
           @Override
           public void onSuccess(DetectResponse detectResponse) {
               String error = detectResponse.getError_message();
               if(error!=null){
                   Toast.makeText(activity,error,Toast.LENGTH_LONG).show();
                   Log.e(TAG,error);
                   return;
               }
               System.out.println("detect:"+detectResponse.toString());
               Intent intent=new Intent();
               intent.setClass(activity,DetectActivity.class);
               ImageResource.getInstance().setDetectResponse(detectResponse);
               //intent.putExtra("data", JSONObject.toJSONString(detectResponse));
               activity.startActivityForResult(intent,2);
           }

           @Override
           public void onFailed(String s) {
               Log.e(TAG, s);
           }
       });
   }

   //对图片进行美颜和美白
   public void beauty_face(final AppCompatActivity activity, byte[] img){
       HashMap<String, String> map = new HashMap<>();
       faceApi.beautify(map, img, new IFacePPCallBack<BeautyResponse>() {
           @Override
           public void onSuccess(BeautyResponse beautyResponse) {
               String error = beautyResponse.getError_message();
               if(error!=null){
                   Toast.makeText(activity,error,Toast.LENGTH_LONG).show();
                   Log.e(TAG,error);
                   return;
               }
               String result = beautyResponse.getResult();
               byte[] decode = Base64.decode(result, Base64.DEFAULT);
               ImageResource.getInstance().setBeauty_img(BitmapFactory.decodeByteArray(decode,0,decode.length));
               Intent intent = new Intent();
               intent.setClass(activity,BeautyActivity.class);
               activity.startActivityForResult(intent,3);
           }

           @Override
           public void onFailed(String s) {
               Log.e(TAG, s);
           }
       });
   }

}

FaceAdapter.java

将数据填充到RecyclerView中

public class FaceAdapter extends RecyclerView.Adapter<ViewHolder> {
    private List<Face> list;
    private Context context;

    public FaceAdapter(Context context){
        this.context=context;
        DetectResponse detectResponse = ImageResource.getInstance().getDetectResponse();
        if(detectResponse!=null){
            this.list=detectResponse.getFaces();
        }

    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.face_item, viewGroup,false);
        ViewHolder viewHolder = new ViewHolder(view) {
            @Override
            public String toString() {
                return super.toString();

            }
        };
        return  viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        View view = viewHolder.itemView;
        FaceAttributes attributes = list.get(i).getAttributes();
        if(attributes==null){
            Toast.makeText(context,"加载失败!",Toast.LENGTH_LONG).show();
            return;
        }
        //System.out.println("item"+jsonObject.toJSONString());
        setItemListener(view,list.get(i).getFace_token());
        ImageView iv = view.findViewById(R.id.iv);
        TextView tv_age = view.findViewById(R.id.age);
        TextView tv_beauty = view.findViewById(R.id.beauty);
        TextView tv_gender = view.findViewById(R.id.gender);
        String age = attributes.getAge().getValue();
        String gender = attributes.getGender().getValue();
        float beauty=0;
        if(gender.equals("Female")){
            gender="女性";
            beauty= attributes.getBeauty().getFemale_score();
        }else {
            gender="男性";
            beauty= attributes.getBeauty().getFemale_score();
        }

        tv_age.setText(tv_age.getText()+age);
        tv_gender.setText(tv_gender.getText()+gender);
        tv_beauty.setText(tv_beauty.getText()+String.valueOf(beauty));

        CommonRect face_rect = list.get(i).getFace_rectangle();
        Bitmap bitmap = Bitmap.createBitmap(
                ImageResource.getInstance().getOrig_img()
                ,face_rect.getLeft()
                ,face_rect.getTop()
                ,face_rect.getWidth()
                ,face_rect.getHeight()
        );
        iv.setImageBitmap(bitmap);
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    private void setItemListener(View view, final String face_token){
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setClass(context,DetailActivity.class);
                intent.putExtra("face_token",face_token);
                context.startActivity(intent);
            }
        });
    }

}

ImageResource.java

采用单例设计模式,管理原始图像,美颜后的图片,人脸分析后的结果,方便在其他activity中使用

//图片资源类
public class ImageResource {
    private Bitmap orig_img;//原始图片
    private Bitmap beauty_img;//美颜后的图片
    private DetectResponse detectResponse;//人脸分析结果

    private static ImageResource instance;

    private ImageResource(){}

    public static ImageResource getInstance(){
        if(instance==null){
            instance=new ImageResource();
        }
        return instance;
    }

    public  void setOrig_img(Bitmap orig_img) {
        this.orig_img = orig_img;
    }

    public  Bitmap getOrig_img() {
        return orig_img;
    }

    public  Bitmap getBeauty_img() {
        return beauty_img;
    }

    public void setBeauty_img(Bitmap beauty_img) {
        this.beauty_img = beauty_img;
    }

    public DetectResponse getDetectResponse() {
        return detectResponse;
    }

    public void setDetectResponse(DetectResponse detectResponse) {
        this.detectResponse = detectResponse;
    }

    public void destory(){
        orig_img=null;
        beauty_img=null;
        detectResponse=null;
    }
}

MainActivity.java

主活动(源码中查看代码):https://gitee.com/zouchengxin/analyze_face/blob/master/app/src/main/java/com/zcx/anlayze_face/MainActivity.java

DetectActivity.java

人脸分析活动(源码中查看代码):https://gitee.com/zouchengxin/analyze_face/blob/master/app/src/main/java/com/zcx/anlayze_face/DetectActivity.java

BeautyActivity.java

美颜分析活动(源码中查看代码):https://gitee.com/zouchengxin/analyze_face/blob/master/app/src/main/java/com/zcx/anlayze_face/BeautyActivity.java

DetailActivity.java

详情活动(源码中查看代码):https://gitee.com/zouchengxin/analyze_face/blob/master/app/src/main/java/com/zcx/anlayze_face/DetailActivity.java

其他

其他一些都是布局文件没啥好说的

最后说一下我遇到的坑,原先我想通过intent(意图)来传图片,结果报如下错误:

FAILED BINDER TRANSACTION !!! (parcel size = 14755544)

最后找到原因:Intent携带数据的大小受限Binder缓存的大小,Binder缓存的大小大约为1M,但有可能其他地方也存在缓存,所以实际大小肯定是小于1Mde的。所以传递小数据时可以用intent携带,但是大数据时就不考虑这种方法了,如果实在是必须使用传递那么可以使用一个操作类来暂存。
之后就采用单例设计模式存储图片了.完美解决问题.

你可能感兴趣的:(android,android,项目,实战,人脸识别,face++)