现如今,人工智能越来越火,以至于我们必须了解和掌握它,今天我们就来结合阿里云的接口来实现人脸定位,人脸检测等功能。
废话不多说,先上效果图:
随便在网上找了三张图片进行检测,检测结果只显示了每一张图片的人脸数,和各个人脸的位置。
该项目的githup地址为:https://github.com/gumaoqi/faceDetect
你可以去将项目clone下来,然后查看或更改来达到自己的需求。
这里我在完成了功能后将ak_id和_ak_secret修改了,你需要自行申请才能正常运行,下面先介绍如何申请key。
首先百度阿里云进入其首页,登录后点击左上角的产品---人工智能---人脸检测定位,进入简介页面,我们可以浏览一下简单介绍,了解了简单介绍后我们点击接口文档详见进入接口页面。
在接口页面,我们可以浏览一下传入的参数和返回的参数的详情,这里我简单介绍一下。
传入参数:type(要检测内容的类型,可以是图片网址和图片的base64内容),image_url(图片网址,若检测的是图片内容可以不填),content(图片内容,若检测的是图片网址可以不填)
主要的返回参数:face_num(人脸数),face_rect(每一个人脸的位置),landmark_num(人脸特征点数目,目前固定一张脸为105个点),landmark(每一个脸的特征点的每一个位置),特征点具体含义如下图:
然后我们点击API校验规范,进入API检验规范页面
在API检验页面中我们可以点击对应的链接进入到管理AccessKey页面,你需要创建你的AccessKey来接入阿里云的接口。
这里需要特别说明的是:阿里云的大多数接口都是需要收费的,所以你需要保护好你的AccessKey,防止你的财产受到损失。
比如说:如果你的AccessKey以明文的形式写入你的程序中,不做安全处理,一旦别人利用反编译等技术获取到你的AccessKey,他将可以使用你的账户余额进行他的操作,后果不堪设想。
申请好了AccessKey返回到API检验规范页面
可以看到,请求需要添加的其他参数有很多,各有各的意义,不过没关系,我们不用去了解这些东西,因为阿里云已经为我们写好了demo,我们是Android程序,所以直接滑倒java的demo,如果你是其他的语言则查看对应的代码,在这里我就不讲解demo的代码了,请自行查看,接下来我们讲解我们程序的代码。
代码结构如下图:
主活动Mainactivity,携带传入参数Body类,获取返回结果FaceRecognitionResult类,进行检测的FaceMatchHelper类,三张被检测的图片。
检测图片需要连接网络,加入网络权限。
build.gradle
implementation 'com.jakewharton:butterknife:8.8.1'
//butterknife
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
//butterknife
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'
//Gson
项目中用到butterknife,添加依赖;项目中用到Gson解析数据,添加依赖。
MainActivity.java
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.google.gson.Gson;
import java.io.ByteArrayOutputStream;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import entity.FaceRecognitionResult;
public class MainActivity extends AppCompatActivity {
private final String TAG = "MainActivity";
@BindView(R.id.activity_main_detect_one_bt)
Button activityMainDetectOneBt;
@BindView(R.id.activity_main_detect_two_bt)
Button activityMainDetectTwoBt;
@BindView(R.id.activity_main_detect_three_bt)
Button activityMainDetectThreeBt;
@BindView(R.id.activity_main_detect_result_one_tv)
TextView activityMainDetectResultOneTv;
@BindView(R.id.activity_main_detect_result_two_tv)
TextView activityMainDetectResultTwoTv;
@BindView(R.id.activity_main_detect_result_three_tv)
TextView activityMainDetectResultThreeTv;
@BindView(R.id.activity_main_detect_one_iv)
ImageView activityMainDetectOneIv;
@BindView(R.id.activity_main_detect_two_iv)
ImageView activityMainDetectTwoIv;
@BindView(R.id.activity_main_detect_three_iv)
ImageView activityMainDetectThreeIv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
activityMainDetectOneIv.setBackgroundResource(R.drawable.wuyanzu);
activityMainDetectTwoIv.setBackgroundResource(R.drawable.heying);
activityMainDetectThreeIv.setBackgroundResource(R.drawable.heying2);
}
@OnClick({R.id.activity_main_detect_one_bt, R.id.activity_main_detect_two_bt, R.id.activity_main_detect_three_bt})
public void onViewClicked(View view) {
Bitmap bitmap;
FaceRecognitionResult recognitionResult;
String str = "";
switch (view.getId()) {
case R.id.activity_main_detect_one_bt:
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.wuyanzu);
recognitionResult = faceRecognition(bitmap);
str = "检测到人脸数为:" + recognitionResult.getFace_num() + ",位置为(分别是[left, top, width, height]):";
for (Integer integer : recognitionResult.getFace_rect()) {
str += integer + ",";
}
activityMainDetectResultOneTv.setText(str);
break;
case R.id.activity_main_detect_two_bt:
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.heying);
recognitionResult = faceRecognition(bitmap);
str = "检测到人脸数为:" + recognitionResult.getFace_num() + ",位置为(分别是[left, top, width, height]):";
for (Integer integer : recognitionResult.getFace_rect()) {
str += integer + ",";
}
activityMainDetectResultTwoTv.setText(str);
break;
case R.id.activity_main_detect_three_bt:
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.heying2);
recognitionResult = faceRecognition(bitmap);
str = "检测到人脸数为:" + recognitionResult.getFace_num() + ",位置为(分别是[left, top, width, height]):";
for (Integer integer : recognitionResult.getFace_rect()) {
str += integer + ",";
}
activityMainDetectResultThreeTv.setText(str);
break;
}
}
/**
* 人脸识别,调用的阿里云人脸识别接口
*
* @param bitmap 需要识别的照片
*/
public FaceRecognitionResult faceRecognition(Bitmap bitmap) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
String result = "";
String url = "https://dtplus-cn-shanghai.data.aliyuncs.com/face/detect";
String ak_id = "aaaaaaaaaaaaaaaaaaaaa"; // 替换成自己的
String ak_secret = "bbbbbbbbbbbbbbbbbbbbbb"; // 替换成自己的
Body bd = new Body();
bd.setType(1);
bd.setImage_url("http://pic4.nipic.com/20090926/2121777_021618818098_2.jpg");
bd.setContent(base64ToNoHeaderBase64(bitmapToBase64(bitmap)));
String body = bd.ToString();
try {
result = FaceMatchHelper.sendPost(url, body, ak_id, ak_secret);
} catch (Exception e) {
e.printStackTrace();
}
Gson gson = new Gson();
FaceRecognitionResult faceRecognitionResult = gson.fromJson(result, FaceRecognitionResult.class);
return faceRecognitionResult;
}
/**
* 将Bitmap转换成Base64字符串
*
* @param bitmap
* @return
*/
public static String bitmapToBase64(Bitmap bitmap) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 40, bos);//参数100表示不压缩
byte[] bytes = bos.toByteArray();
//转换来的base64码需要加前缀,必须是NO_WRAP参数,表示没有空格。
return "data:image/jpeg;base64," + Base64.encodeToString(bytes, Base64.NO_WRAP);
//转换来的base64码不需要需要加前缀,必须是NO_WRAP参数,表示没有空格。
//return "data:image/jpeg;base64," + Base64.encodeToString(bytes, Base64.NO_WRAP);
}
/**
* 将base64的头去掉
*
* @param base64
* @return
*/
public static String base64ToNoHeaderBase64(String base64) {
return base64.replace("data:image/jpeg;base64,", "");
}
}
点击button检测对应的imageview上的图片并将相应的内容显示在textview中。
bitmapToBase64函数将Bitmap转换成Base64字符串。
base64ToNoHeaderBase64函数将Base64字符串去掉头。
Body.java
public class Body {
int type;
String image_url;
String content;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getImage_url() {
return image_url;
}
public void setImage_url(String image_url) {
this.image_url = image_url;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String ToString() {
if (type == 1) {
return "{\"type\":1,\"content\":\"" + content + "\"}";
}
return "{\"type\":0,\"image_url\":\"" + image_url + "\"}";
}
}
携带检测内容的类,type为1检测图片内容,其他检测图片网址。
FaceRecognitionResult.java为GsonFormat自动生成的类。
FaceMatchHelper为根据阿里云的demo写的类。
activity_main.xml为布局文件,请自行查看。
至此,已成功利用阿里云的接口实现了人脸检测的内容,检测了三张程序中的图片,具体应用时,图片可以来自摄像头、图库和网络,通过人脸检测达到不同的功能。
人脸识别和人脸对比大同小异,我这里就偷个懒不贴出来了,请自行完成。
博主水平有限,如有指正错误和其他建议请在评论区留言。
市面上有许多人工智能的接口,比如说:百度云和腾讯云等。为什么我选择的是阿里云呢?因为我公司使用的服务器是租用阿里云的,有对应的账号,所以直接就使用的阿里云的接口。
其实这些产品大同小异,只要参照其文档都能达到想要的要求,在选择的时候尽量选择大公司的产品,这样出现问题的时候能有专人为你处理。