检测人脸有很多用处, 可以提供更好的交互, 和一些有针对性的意见. 检测脸部关键信息, 也可以处理一些微表情的内容.
Google推出了官方的人脸检测功能, 很不幸依赖Google Service, 需要版本8.1以上. 国内手机基本不会默认配置. 下载地址, 此版本适配手机系统4.4+.
本文的GitHub下载地址
关注:
(1) 如何提取人脸(Face)位置.
(2) 如何提取脸部关键点(Landmark)位置.
(3) 如何在画布(Canvas)创建居中图片控件.
我讲解一下用法, 写了一个简单的显示控件, 注释详细.
配置项目
新建HelloWorld项目, 配置build.gradle
.1
2compile 'com.google.android.gms:play-services-vision:8.1.0' // 包含人脸识别类
compile 'com.jakewharton:butterknife:7.0.1'
一般都会从最基础的HelloWorld开始, 方便学习和理解. ButterKnife必用.
检测人脸控件
控件居中显示一张图片, 在图片上, 绘制人脸位置和关键点(Landmarks).
关键点包括: 眼睛, 鼻子, 嘴等属性. 存在遮挡, 根据不同人脸提取量不同.
通过FaceDetector
检测Bitmap
, 获取图片的所有脸部(face)信息.
根据位置(Position)画出脸的形状, 根据关键点(Landmarks)画出脸部特征.
同时可以获取各种特征的概率(Probability), 和脸部偏移.
1 | /** |
图像和特征是显示在画布上, 根据画布大小, 等比例缩放, 并居中显示.
主页面
主界面通过一个简单的ViewPager连续显示图片.1
2
3
4
5
6
7
8
9
10
11
12// 连续 (R.id.main_vp_container) ViewPager mVpContainer;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mVpContainer.setAdapter(new FacesViewPagerAdapter(getSupportFragmentManager()));
}
适配传递参数, 根据参数, 返回不同的图片页面.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21/**
* 脸部适配器
* <p/>
* Created by wangchenlong on 15/12/15.
*/
public class FacesViewPagerAdapter extends FragmentPagerAdapter {
private static final int NUM = 9;
public FacesViewPagerAdapter(FragmentManager fm) {
super(fm);
}
public Fragment getItem(int position) {
return ShowFaceFragment.newInstance(position);
}
public int getCount() {
return NUM;
}
}
每页是个Fragment, 根据参数, 使用不同资源.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52/**
* 显示人脸的界面
* <p/>
* Created by wangchenlong on 15/12/15.
*/
public class ShowFaceFragment extends Fragment {
private static final String ARG_SELECTION_NUM = "arg_selection_num";
(R.id.main_fdv_face_detector) FacesDisplayView mFdvFaceDetector;
// 图片集合 ArrayList<Integer> mPhotos;
public ShowFaceFragment() {
mPhotos = new ArrayList<>();
mPhotos.add(R.raw.total_large_poster);
mPhotos.add(R.raw.jessicajung_large_poster);
mPhotos.add(R.raw.seohyun_large_poster);
mPhotos.add(R.raw.sooyoung_large_poster);
mPhotos.add(R.raw.sunny_large_poster);
mPhotos.add(R.raw.taeyeon_large_poster);
mPhotos.add(R.raw.tiffany_large_poster);
mPhotos.add(R.raw.yoona_large_poster);
mPhotos.add(R.raw.yuri_large_poster);
}
public static ShowFaceFragment newInstance(int selectionNum) {
ShowFaceFragment simpleFragment = new ShowFaceFragment();
Bundle args = new Bundle();
args.putInt(ARG_SELECTION_NUM, selectionNum);
simpleFragment.setArguments(args);
return simpleFragment;
}
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_show_face, container, false);
ButterKnife.bind(this, view);
return view;
}
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
int image = mPhotos.get(getArguments().getInt(ARG_SELECTION_NUM));
InputStream stream = getResources().openRawResource(image);
Bitmap bitmap = BitmapFactory.decodeStream(stream);
mFdvFaceDetector.setBitmap(bitmap);
}
public void onDestroyView() {
super.onDestroyView();
ButterKnife.unbind(this);
}
}
注意使用注释(Annotation), 判断资源类型, 如
@RawRes
.
有时间再完善一下这个小控件吧.
OK, that’s all! Enjoy It!
原始地址:
http://www.wangchenlong.org/2016/03/22/1603/225-face-detect/
欢迎Follow我的GitHub, 关注我的简书, 微博, CSDN, 掘金, Slides.
我已委托“维权骑士”为我的文章进行维权行动. 未经授权, 禁止转载, 授权或合作请留言.