Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15436
  • 博文数量: 11
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 120
  • 用 户 组: 普通用户
  • 注册时间: 2019-12-06 11:01
文章分类
文章存档

2020年(6)

2019年(5)

我的朋友
最近访客

分类: Java

2019-12-23 00:00:46

最近在尝试做一个人脸识别项目,在对比几款主流人脸识别SDK后,采用了虹软的Arcface SDK,因为它提供了免费版本,并且可以离线使用,接入难度也比较低。项目中有一个需求就是显示检测到的人脸,但是如何从一张图片中抠取合适大小的人脸呢?本文将从以下步骤来介绍如何实现:

1. 如何获得人脸框
2. 如何根据人脸框裁剪
3. 如何进行结果图旋转
4. 应用场景举例

1. 如何获得人脸框

首先我们来看一下虹软Android ArcFace SDK用于人脸检测的detectFaces函数以及人脸数据类FaceInfo:
detectFaces函数:

参数 类型 说明
data byte[] 图像数据的内存
width int 图像的宽
height int 图像的高
format int 图像的格式
faceInfoList List 人脸检测结果列表

FaceInfo定义:

参数 类型 说明
rect Rect 人脸在图像中的坐标
orient int 人脸的朝向
faceId int 人脸id,用于标识人脸

人脸检测函数介绍的文章有很多,这里就不多做介绍了。FaceInfo中的rect就是我们用来抠取人脸的重要参数,下图就是根据它画出的人脸框。


2. 如何根据人脸框裁剪

以Android平台为例,Bitmap类提供了函数createBitmap(Bitmap source, int x, int y, int width, int height)

参数 类型 说明
source Bitmap 原始图像
x int 人脸框左上角y坐标
y int 人脸框左上角y坐标
width int 新图像的宽
height int 新图像的高

使用这个函数就可以抠取任意区域内图像内容:

//原图 Bitmap source; //人脸框 Rect faceRect;  //创建Bitmap Bitmap.createBitmap(source,faceRect.left,faceRect.top,faceRect.width(),faceRect.height();

2. 如何根据人脸框裁剪

以Android平台为例,Bitmap类提供了函数createBitmap(Bitmap source, int x, int y, int width, int height)

参数 类型 说明
source Bitmap 原始图像
x int 人脸框左上角y坐标
y int 人脸框左上角y坐标
width int 新图像的宽
height int 新图像的高

使用这个函数就可以抠取任意区域内图像内容:

//原图 Bitmap source;  //人脸框 Rect faceRect;  //创建Bitmap Bitmap.createBitmap(source,faceRect.left,faceRect.top,faceRect.width(),faceRect.height();


3. 如何进行结果图旋转

FaceInfo中orient代表这个人脸在图像中的朝向,当其不为0°的时候,需要根据实际情况进行旋转。

旋转角度 类型 说明
ASF_OC_0 int
ASF_OC_90 int 逆时针90°
ASF_OC_180 int 180°
ASF_OC_270 int 顺时针90°

以下是旋转代码

//原图 Bitmap source;  //人脸框 Rect faceRect;  //创建Bitmap,假设需要顺时针旋转90° Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap.createBitmap(source, faceRect.left, faceRect.top, faceRect.width(),
faceRect.height(), matrix, true);

4. 应用场景举例

例如门禁场景下,需要显示人脸(抠图)或者上传人脸图片到服务端。如果上传完整的图像,则会占用大量的存储空间以及网络资源,所以上传抠取的人脸图片是比较合适的,但是根据检测所得的人脸框抠取的人脸是不完整的,所以需要对人脸框做一些后期处理,最简单的方案就是宽高分别向外扩大其1/2长度。示例代码如下:

//原图 Bitmap source; //人脸框 Rect faceRect; //调整人脸框 Rect newRect = new Rect(faceRect); //确保人脸框在图像内  if (newRect.left < 0) {
    newRect.left = 0;
}  if (newRect.top < 0) {
    newRect.top = 0;
}  if (newRect.right > source.getWidth()) {
    newRect.right =
source.getWidth();
}  if (newRect.bottom > source.getHeight()) {
    newRect.bottom =
source.getHeight();
}  //  int offsetX = Math.min(Math.min(faceRect.width()/2,newRect.left),
source.getWidth() - newRect.right); int offsetY = Math.min(Math.min(faceRect.height()/2,newRect.top),
source.getHeight() - newRect.bottom);
newRect.inset(-offsetX, -offsetY);  //创建Bitmap,假设需要顺时针旋转90° Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap.createBitmap(source, newRect.left, newRect.top, newRect.width(),
newRect.height(), matrix, true);

温馨提示:

虹软人脸识别Android Demo中提供了很多人脸识别相关功能,如:画人脸框适配方案;异步人脸特征提取;异步人脸特征比对等等,有需要可以在下面链接下载:
Android Demo可在下载


阅读(1192) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~