Android人脸识别app——基于Face,今天带你详细了解各组件原理

e.printStackTrace();

}

if (returnBm == null) {

returnBm = bm;

}

if (bm != returnBm) {

bm.recycle();

}

return returnBm;

}

封装了两个方法,依次调用可以解决三星手机照片的问题。两个方法主要的工作就是,得到取出来的照片被旋转的角度,然后再将角度旋转回去,就可以得到原来的照片。因为并不是所有的手机在获取照片时,照片都会被旋转,所以得先判断一下照片有没有被旋转,再决定是否需要将它旋转调整。

行,这样最后就获得到了正确的 BitMap 照片,可以进行下一步了。

传照片获取数据

传照片获取数据,主要是运用了 Retrofit 和 RxJava 的封装。请求的参数可以参考 Face++ 的官方文档。

/**

  • retrofit 面部识别请求的网络服务

  • @author chaochaowu

*/

public interface FaceppService {

/**

  • @param apikey

  • @param apiSecret

  • @param imageBase64

  • @param returnLandmark

  • @param returnAttributes

  • @return

*/

@POST(“facepp/v3/detect”)

@FormUrlEncoded

Observable getFaceInfo(@Field(“api_key”) String apikey,

@Field(“api_secret”) String apiSecret,

@Field(“image_base64”) String imageBase64,

@Field(“return_landmark”) int returnLandmark,

@Field(“return_attributes”) String returnAttributes);

}

照片需要进行 base64 转码后上传至服务器,封装了一个照片base64转码方法。

public static String base64(Bitmap bitmap){

ByteArrayOutputStream baos = new ByteArrayOutputStream();

bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

byte[] bytes = baos.toByteArray();

return Base64.encodeToString(bytes, Base64.DEFAULT);

}

处理完成之后就可以进行网络请求获取数据。

@Override

public void getDetectResultFromServer(final Bitmap photo) {

String s = Utils.base64(photo);

faceppService.getFaceInfo(BuildConfig.API_KEY, BuildConfig.API_SECRET, s, 1, “gender,age,smiling,emotion,beauty”)

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Observer() {

@Override

public void onSubscribe(Disposable d) {

mView.showProgress();

}

@Override

public void onNext(FaceppBean faceppBean) {

handleDetectResult(photo,faceppBean);

}

@Override

public void onError(Throwable e) {

mView.hideProgress();

}

@Override

public void onComplete() {

mView.hideProgress();

}

});

}

Face++ 服务器会对我们上传的照片进行处理,分析照片中的人脸信息,并以 json 形式返回,返回的数据将被放入我们定义的bean类中。

/**

  • 面部识别结果的bean

  • @author chaochaowu

*/

public class FaceppBean {

/**

  • image_id : Dd2xUw9S/7yjr0oDHHSL/Q==

  • request_id : 1470472868,dacf2ff1-ea45-4842-9c07-6e8418cea78b

  • time_used : 752

  • faces : [{“landmark”:{“mouth_upper_lip_left_contour2”:{“y”:185,“x”:146},“contour_chin”:{“y”:231,“x”:137},“right_eye_pupil”:{“y”:146,“x”:205},“mouth_upper_lip_bottom”:{“y”:195,“x”:159}},“attributes”:{“gender”:{“value”:“Female”},“age”:{“value”:21},“glass”:{“value”:“None”},“headpose”:{“yaw_angle”:-26.625063,“pitch_angle”:12.921974,“roll_angle”:22.814377},“smile”:{“threshold”:30.1,“value”:2.566890001296997}},“face_rectangle”:{“width”:140,“top”:89,“left”:104,“height”:141},“face_token”:“ed319e807e039ae669a4d1af0922a0c8”}]

*/

private String image_id;

private String request_id;

private int time_used;

private List faces;

…显示部分内容

bean 类中有人脸识别得到的 性别、年龄、颜值、情绪等信息,还有每张人脸在照片中的坐标位置。接下来的工作就是对这些数据进行处理。

获取信息后的数据处理

数据的处理主要就两件事,一个是将数据以文字的形式展现,这个很简单,就不介绍了,还有一个就是将人脸在照片中标示出来,这个需要对 BitMap 进行处理,利用数据中人脸在照片中的坐标位置,我们用方框将人脸标识出来。

private Bitmap markFacesInThePhoto(Bitmap bitmap, List<FaceppBean.FacesBean> faces) {

Bitmap tempBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);

Canvas canvas = new Canvas(tempBitmap);

Paint paint = new Paint();

paint.setColor(Color.RED);

paint.setStyle(Paint.Style.STROKE);

paint.setStrokeWidth(10);

for (FaceppBean.FacesBean face : faces) {

FaceppBean.FacesBean.FaceRectangleBean faceRectangle = face.getFace_rectangle();

int top = faceRectangle.getTop();

int left = faceRectangle.getLeft();

int height = faceRectangle.getHeight();

int width = faceRectangle.getWidth();

canvas.drawRect(left, top, left + width, top + height, paint);

}

return tempBitmap;

}

封装了一个方法,运用 Canvas 在照片上进行绘制,因为照片中的人脸可能不止一个,所以用for循环遍历。获取人脸在照片中的坐标,利用人脸左上角的坐标以及人脸的宽高,在照片中绘制一个方框将人脸标出。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

最后

代码真的是重质不重量,质量高的代码,是当前代码界提倡的,当然写出高质量的代码肯定需要一个相当高的专业素养,这需要在日常的代码书写中逐渐去吸收掌握,谁不是每天都在学习呀,目的还不是为了一个,为实现某个功能写出高质量的代码。

所以,长征路还长,大家还是好好地做个务实的程序员吧。

最后,小编这里有一系列Android提升学习资料,有兴趣的小伙伴们可以来看下哦~

我的 Android 学习,面试文档,视频收集大整理

…(img-WCB76dgs-1711046212348)]

最后

代码真的是重质不重量,质量高的代码,是当前代码界提倡的,当然写出高质量的代码肯定需要一个相当高的专业素养,这需要在日常的代码书写中逐渐去吸收掌握,谁不是每天都在学习呀,目的还不是为了一个,为实现某个功能写出高质量的代码。

所以,长征路还长,大家还是好好地做个务实的程序员吧。

最后,小编这里有一系列Android提升学习资料,有兴趣的小伙伴们可以来看下哦~

我的 Android 学习,面试文档,视频收集大整理

  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值