Android手把手教你使用阿里云接口实现人脸定位、人脸检测、人脸对比功能。

前言

现如今,人工智能越来越火,以至于我们必须了解和掌握它,今天我们就来结合阿里云的接口来实现人脸定位,人脸检测等功能。

废话不多说,先上效果图:

随便在网上找了三张图片进行检测,检测结果只显示了每一张图片的人脸数,和各个人脸的位置。

该项目的githup地址为:https://github.com/gumaoqi/faceDetect

你可以去将项目clone下来,然后查看或更改来达到自己的需求。

这里我在完成了功能后将ak_id和_ak_secret修改了,你需要自行申请才能正常运行,下面先介绍如何申请key。

查看接口文档以及申请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类,三张被检测的图片。


<uses-permission android:name="android.permission.INTERNET" />


检测图片需要连接网络,加入网络权限。

 

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为布局文件,请自行查看。

 

至此,已成功利用阿里云的接口实现了人脸检测的内容,检测了三张程序中的图片,具体应用时,图片可以来自摄像头、图库和网络,通过人脸检测达到不同的功能。

人脸识别和人脸对比大同小异,我这里就偷个懒不贴出来了,请自行完成。

博主水平有限,如有指正错误和其他建议请在评论区留言。

后记

市面上有许多人工智能的接口,比如说:百度云和腾讯云等。为什么我选择的是阿里云呢?因为我公司使用的服务器是租用阿里云的,有对应的账号,所以直接就使用的阿里云的接口。

其实这些产品大同小异,只要参照其文档都能达到想要的要求,在选择的时候尽量选择大公司的产品,这样出现问题的时候能有专人为你处理。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
好的,我知道你的问题了。关于Python实现面部特效,我可以向你介绍一下Python库Face_recognition,它可以实现人脸识别和面部特效。 Face_recognition是一个基于Python的人脸识别库,它使用dlib库来实现人脸识别,可以检测和识别图像中的人脸,并提取面部特征,比如眼睛、鼻子、嘴巴等部位的位置和轮廓。 具体实现过程如下: 1. 首先需要安装Face_recognition库和dlib库,可以使用pip install face_recognition和pip install dlib命令来安装。 2. 导入Face_recognition库和Pillow库,使用load_image_file函数加载需要处理的图片。 3. 使用face_locations函数来获取图像中人脸的位置坐标,使用face_landmarks函数来获取面部特征的位置坐标。 4. 使用Pillow库的ImageDraw模块来绘制面部特征,比如眼睛、鼻子、嘴巴等部位的位置和轮廓。 下面是一个简单的示例代码,实现在图片中绘制人脸位置和面部特征: ``` import face_recognition from PIL import Image, ImageDraw # 加载图片 image = face_recognition.load_image_file("test.jpg") # 获取人脸位置坐标 face_locations = face_recognition.face_locations(image) # 获取面部特征位置坐标 face_landmarks = face_recognition.face_landmarks(image) # 绘制人脸位置 for face_location in face_locations: top, right, bottom, left = face_location draw = ImageDraw.Draw(image) draw.rectangle(((left, top), (right, bottom)), outline=(255, 0, 0), width=2) # 绘制面部特征 for face_landmark in face_landmarks: for name, points in face_landmark.items(): draw = ImageDraw.Draw(image) draw.line(points, fill=(255, 255, 255), width=2) # 保存绘制后的图片 image.save("result.jpg") ``` 这样就可以实现简单的面部特效了。当然,Face_recognition库还有很多其他的功能和用法,你可以查看官方文档来了解更多。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值