阿里云人脸搜索最佳实践

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,内容安全 1000次 1年
对象存储 OSS,恶意文件检测 1000次 1年
简介: 人脸人体识别技术是基于阿里云深度学习算法,结合图像或视频的人脸检测、分析、比对以及人体检测等技术,为您提供人脸人体的检测定位、人脸属性识别和人脸比对等能力。阿里云视觉智能开放平台提供1:N人脸查找的功能,在向人脸库添加Face的时候,算法会根据添加的人脸计算一组特征记录到后端,但是并不会保存原始图片,这样在查询人脸的时候,就无法返回原始图片。很多用户使用过程中都有这样的使用场景:希望查询人脸的时候,将对应的相似人脸的原始图片也返回。这里结合阿里云oss服务,通过用户侧自己在oss保存图片的方式,实现查询人脸后不仅返回相似人脸样本信息,也返回原始图片的效果。

Step By Step

1、pom.xml
    <dependencies>
        <!--添加oss相关依赖-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.10.2</version>
        </dependency>

        <!--java核心库-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.4.8</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.52</version>
        </dependency>

        <!-- 人脸识别相关API -->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-facebody</artifactId>
            <version>1.0.8</version>
        </dependency>
    </dependencies>
2、完整的Java Code Sample
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.google.gson.Gson;
import com.aliyuncs.facebody.model.v20191230.*;
import java.io.File;

public class SearchFaceDemo {

    // yourEndpoint填写Bucket所在地域对应的Endpoint。viapi绝大部分api目前仅支持上海区域oss,所以这里需要创建上海区域bucket,Endpoint填写为https://oss-cn-shanghai.aliyuncs.com。
    static String ossEndpoint = "https://oss-cn-shanghai.aliyuncs.com";
    static String bucketName = "<oss bucket>";
    static String ossDir = "facepics";  // 在oss bucket下面手动创建的文件夹
    // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
    static String accessKeyId = "<ak>";
    static String accessKeySecret = "<sk>";
    // 创建OSSClient实例。
    static OSS ossClient = new OSSClientBuilder().build(ossEndpoint, accessKeyId, accessKeySecret);

    private static DefaultProfile profile = DefaultProfile.getProfile("cn-shanghai", accessKeyId, accessKeySecret);
    private static IAcsClient client = new DefaultAcsClient(profile);

    public static void main(String[] args) {

        // 1、人脸查找数据准备
        String dbName = "group1";
        String wangfei1 = "C:\\Users\\Administrator\\Desktop\\新建文件夹\\face1.jpg";
        String wangfei2 = "C:\\Users\\Administrator\\Desktop\\新建文件夹\\face2.jpg";
        String jingtian1 = "C:\\Users\\Administrator\\Desktop\\新建文件夹\\jingtian1.jpeg";
        String jingtian2 = "C:\\Users\\Administrator\\Desktop\\新建文件夹\\jingtian2.jpeg";

        // 2、创建FaceDB
//        createFaceDbRequest(dbName);

        // 3、添加人脸样本
//        String entityId1 = "wangfei";
//        String entityId2 = "jingtian";
//
//        addFaceEntity(dbName, entityId1);
//        addFaceEntity(dbName, entityId2);

        // 4、为样本添加人脸图片,注意本部分将图片url地址添加到:ExtraData参数
//        addFace(dbName,entityId1,uploadPicGetUrl(wangfei1));
//        addFace(dbName,entityId1,uploadPicGetUrl(wangfei2));
//        addFace(dbName,entityId2,uploadPicGetUrl(jingtian1));
//        addFace(dbName,entityId2,uploadPicGetUrl(jingtian2));

        // 5、查询目前人脸库的样本情况
//        listFaceEntities(dbName, 0);

        // 6、人脸搜索(人脸搜索功能可以根据输入图片,在数据库中搜索并返回相似的人脸图片数据。)
        searchFace(dbName,uploadPicGetUrl(wangfei1),2);

    }

    /**
     * 向oss上传文件,返回公共可读的oss 图片地址
     * @param filePath  图片本地路径
     * @return  oss url
     */
    public static String uploadPicGetUrl(String filePath)
    {
        // 创建PutObjectRequest对象。
        // 依次填写Bucket名称(例如examplebucket)、Object完整路径(例如exampledir/exampleobject.txt)和本地文件的完整路径。Object完整路径中不能包含Bucket名称。
        // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件,这里在ossbucket下面创建目录facepics用于存储上传的图片
        File file = new File(filePath);
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, ossDir+"/" + file.getName(), new File(filePath));

        // 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
         ObjectMetadata metadata = new ObjectMetadata();
        // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
         metadata.setObjectAcl(CannedAccessControlList.PublicRead);  //为了方便获取的文件的公网读路径,这里设置文件的访问权限为公共读
         putObjectRequest.setMetadata(metadata);

        // 上传文件。
        ossClient.putObject(putObjectRequest);
        return "https://" + bucketName + ".oss-cn-shanghai.aliyuncs.com" + "/"+ossDir+"/" + file.getName();
    }

    /**
     * 创建人脸数据库
     * @param dbName 数据库名称
     */
    private static void createFaceDbRequest(String dbName)
    {
        CreateFaceDbRequest createFaceDbRequest = new CreateFaceDbRequest();
        createFaceDbRequest.setName(dbName);

        try {
            CreateFaceDbResponse response = client.getAcsResponse(createFaceDbRequest);
            System.out.println("创建人脸数据库:");
            System.out.println(new Gson().toJson(response));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }

    /**
     * 查看数据库列表
     */
    private static void listFaceDbs()
    {
        ListFaceDbsRequest listFaceDbsRequest = new ListFaceDbsRequest();
        try {
            ListFaceDbsResponse response = client.getAcsResponse(listFaceDbsRequest);
            System.out.println("查看数据库列表: ");
            System.out.println(new Gson().toJson(response));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }

    /**
     * 添加人脸样本
     * @param dbName 数据库名称
     * @param entityId 实体ID
     */
    private static void addFaceEntity(String dbName, String entityId)
    {
        AddFaceEntityRequest addFaceEntityRequest = new AddFaceEntityRequest();
        addFaceEntityRequest.setDbName(dbName);
        addFaceEntityRequest.setEntityId(entityId);
        try{
            AddFaceEntityResponse addFaceEntityResponse = client.getAcsResponse(addFaceEntityRequest);
            System.out.println("添加人脸样本:");
            System.out.println(new Gson().toJson(addFaceEntityResponse));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }

    /**
     * 查询人脸样本
     * @param dbName 数据库名称
     * @param entityId 实体ID
     */
    private static void getFaceEntity(String dbName, String entityId)
    {
        GetFaceEntityRequest getFaceEntityRequest = new GetFaceEntityRequest();
        getFaceEntityRequest.setDbName(dbName);
        getFaceEntityRequest.setEntityId(entityId);
        try{
            GetFaceEntityResponse getFaceEntityResponse = client.getAcsResponse(getFaceEntityRequest);
            System.out.println("查询人脸样本:");
            System.out.println(new Gson().toJson(getFaceEntityResponse));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }

    /**
     * 查询人脸样本列表
     * @param dbName 数据库名称
     * @param Offset 起始记录
     */
    private static void listFaceEntities(String dbName, Integer Offset)
    {
        ListFaceEntitiesRequest listFaceEntitiesRequest = new ListFaceEntitiesRequest();
        listFaceEntitiesRequest.setDbName(dbName);
        listFaceEntitiesRequest.setOffset(Offset);
        try{
            ListFaceEntitiesResponse listFaceEntitiesResponse = client.getAcsResponse(listFaceEntitiesRequest);
            System.out.println("查询人脸样本列表:");
            System.out.println(new Gson().toJson(listFaceEntitiesResponse));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }


    /**
     * 更新人脸样本
     * @param dbName 数据库名称
     * @param entityId 实体ID
     * @param labels 标签名称
     */
    private static void updateFaceEntity(String dbName, String entityId, String labels)
    {
        UpdateFaceEntityRequest updateFaceEntityRequest = new UpdateFaceEntityRequest();
        updateFaceEntityRequest.setDbName(dbName);
        updateFaceEntityRequest.setEntityId(entityId);
        updateFaceEntityRequest.setLabels(labels);
        try{
            UpdateFaceEntityResponse updateFaceEntityResponse = client.getAcsResponse(updateFaceEntityRequest);
            System.out.println("更新人脸样本:");
            System.out.println(new Gson().toJson(updateFaceEntityResponse));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }

    /**
     * 删除人脸样本
     * @param dbName 数据库名称
     * @param entityId 实体ID
     */
    private static void deleteFaceEntity(String dbName, String entityId)
    {
        DeleteFaceEntityRequest deleteFaceEntityRequest = new DeleteFaceEntityRequest();
        deleteFaceEntityRequest.setDbName(dbName);
        deleteFaceEntityRequest.setEntityId(entityId);
        try{
            DeleteFaceEntityResponse deleteFaceEntityResponse = client.getAcsResponse(deleteFaceEntityRequest);
            System.out.println("删除人脸样本:");
            System.out.println(new Gson().toJson(deleteFaceEntityResponse));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }

    /**
     * 添加人脸数据
     * @param dbName 数据库名称
     * @param entityId 实体ID
     * @param imageUrl 人脸图片地址,必须是同Region的OSS的图片地址。人脸必须是正面无遮挡单人人脸。
     */
    private static void addFace(String dbName, String entityId, String imageUrl)
    {
        AddFaceRequest addFaceRequest = new AddFaceRequest();
        addFaceRequest.setDbName(dbName);
        addFaceRequest.setEntityId(entityId);
        addFaceRequest.setImageUrl(imageUrl);
        addFaceRequest.setExtraData(imageUrl);// 注意,此处将图片地址保持到ExtraData中,为后续查询提供方便

        try{
            AddFaceResponse addFaceResponse = client.getAcsResponse(addFaceRequest);
            System.out.println("添加人脸数据:");
            System.out.println(new Gson().toJson(addFaceResponse));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }

    /**
     * 搜索人脸
     * @param dbName 数据库名称
     * @param imageUrl 图片URL地址。必须是同Region的OSS地址。
     */
    private static void searchFace(String dbName, String imageUrl, Integer limit)
    {
        SearchFaceRequest searchFaceRequest = new SearchFaceRequest();
        searchFaceRequest.setDbName(dbName);
        searchFaceRequest.setImageUrl(imageUrl);
        searchFaceRequest.setLimit(limit);
        try{
            SearchFaceResponse searchFaceResponse = client.getAcsResponse(searchFaceRequest);
            System.out.println("搜索人脸:");
            System.out.println(new Gson().toJson(searchFaceResponse));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }

    /**
     * 删除数据库
     * @param dbName 数据库名称
     */
    private static void deleteFace(String dbName, String faceId)
    {
        DeleteFaceRequest deleteFaceRequest = new DeleteFaceRequest();
        deleteFaceRequest.setDbName(dbName);
        deleteFaceRequest.setFaceId(faceId);
        try{
            DeleteFaceResponse deleteFaceResponse = client.getAcsResponse(deleteFaceRequest);
            System.out.println("删除人脸:");
            System.out.println(new Gson().toJson(deleteFaceResponse));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }

    /**
     * 删除数据库
     * @param dbName 数据库名称
     */
    private static void deleteFaceDb(String dbName)
    {
        DeleteFaceDbRequest deleteFaceDbRequest = new DeleteFaceDbRequest();
        deleteFaceDbRequest.setName(dbName);
        try{
            DeleteFaceDbResponse deleteFaceDbResponse = client.getAcsResponse(deleteFaceDbRequest);
            System.out.println("删除数据库:");
            System.out.println(new Gson().toJson(deleteFaceDbResponse));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }

    /**
     * 人脸对比
     * @param imageURLA 待对比图片URL地址A
     * @param imageURLB 待对比图片URL地址B
     */
    private static void compareFace(String imageURLA, String imageURLB)
    {
        CompareFaceRequest compareFaceRequest = new CompareFaceRequest();
        compareFaceRequest.setImageURLA(imageURLA);
        compareFaceRequest.setImageURLB(imageURLB);
        try{
            CompareFaceResponse compareFaceResponse = client.getAcsResponse(compareFaceRequest);
            System.out.println("人脸对比:");
            System.out.println(new Gson().toJson(compareFaceResponse));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }
}
3、查询结果
extraData对应的值即为对应样本人脸的原始图片地址。
搜索人脸:
{"requestId":"60981448-DC3B-518D-82B1-7**********","data":{"matchList":[{"faceItems":[{"faceId":"9770860","score":1.0,"extraData":"https://taro-shangai.oss-cn-shanghai.aliyuncs.com/facepics/face1.jpg","entityId":"wangfei"},{"faceId":"9770861","score":0.7668418,"extraData":"https://taro-shangai.oss-cn-shanghai.aliyuncs.com/facepics/face2.jpg","entityId":"wangfei"}],"location":{"x":217,"y":110,"width":170,"height":233}}]}}
4、使用说明
如果对1:N人脸查找流程使用有疑问,建议可以重点参考: 阿里云视觉智能开放平台--人脸识别使用教程或者 人脸搜索教程

相关参考

人脸搜索1:N

相关实践学习
借助OSS搭建在线教育视频课程分享网站
本教程介绍如何基于云服务器ECS和对象存储OSS,搭建一个在线教育视频课程分享网站。
相关文章
|
21天前
|
人工智能 关系型数据库 数据库
Perplexideez:开源本地 AI 搜索助手,智能搜索信息来源追溯
Perplexideez 是一款开源的本地 AI 搜索助手,旨在通过智能搜索和信息来源追溯功能,提升用户的搜索体验。它支持多用户、单点登录(SSO),并提供美观的搜索结果展示。Perplexideez 基于 Postgres 数据库,集成了 Ollama 或 OpenAI 兼容的端点,使用 SearXNG 实例进行网络搜索。
69 14
Perplexideez:开源本地 AI 搜索助手,智能搜索信息来源追溯
|
6月前
|
文字识别 算法 API
视觉智能开放平台产品使用合集之人脸搜索返回的数据集,是如何进行排序的
视觉智能开放平台是指提供一系列基于视觉识别技术的API和服务的平台,这些服务通常包括图像识别、人脸识别、物体检测、文字识别、场景理解等。企业或开发者可以通过调用这些API,快速将视觉智能功能集成到自己的应用或服务中,而无需从零开始研发相关算法和技术。以下是一些常见的视觉智能开放平台产品及其应用场景的概览。
|
5月前
|
计算机视觉
人脸搜索
【7月更文挑战第31天】人脸搜索。
59 3
|
5月前
|
人工智能 自然语言处理 搜索推荐
阿里云搜索开发工作台:打造智能语义搜索与RAG链路
随着大数据时代的信息爆炸,传统关键字搜索难以满足精准需求。阿里云搜索开发工作台集成AI技术和语义理解,助力企业快速构建智能语义搜索与RAG系统。该平台支持多源数据接入、NLP查询分析、高级排序算法及效果评估工具,并集成大规模预训练模型提升搜索质量。构建流程涵盖数据准备、索引构建、查询分析、文档检索、结果生成及展示。应用场景包括客户支持、内容推荐、电商搜索和新闻聚合等,极大提升了搜索的准确性和用户体验。
|
5月前
|
人工智能 自然语言处理 搜索推荐
阿里云搜索开发工作台:快速搭建AI语义搜索与RAG链路的深度解析
阿里云搜索开发工作台凭借其丰富的组件化服务和强大的模型能力,为企业快速搭建AI语义搜索及RAG链路提供了有力支持。通过该平台,企业可以灵活调用各种服务,实现高效的数据处理、查询分析、索引构建和文本生成等操作,从而大幅提升信息获取与处理能力。随着AI技术的不断发展,阿里云搜索开发工作台将继续优化和完善其服务,为企业数字化转型和智能化升级注入更强动力。
181 0
|
6月前
|
文字识别 小程序 算法
视觉智能开放平台产品使用合集之人脸搜索接口如何自动过滤
视觉智能开放平台是指提供一系列基于视觉识别技术的API和服务的平台,这些服务通常包括图像识别、人脸识别、物体检测、文字识别、场景理解等。企业或开发者可以通过调用这些API,快速将视觉智能功能集成到自己的应用或服务中,而无需从零开始研发相关算法和技术。以下是一些常见的视觉智能开放平台产品及其应用场景的概览。
|
6月前
|
文字识别 算法 API
视觉智能开放平台产品使用合集之人脸搜索的添加人脸样本里的标签属性,查询的结果是一整个字符串,是什么原因
视觉智能开放平台是指提供一系列基于视觉识别技术的API和服务的平台,这些服务通常包括图像识别、人脸识别、物体检测、文字识别、场景理解等。企业或开发者可以通过调用这些API,快速将视觉智能功能集成到自己的应用或服务中,而无需从零开始研发相关算法和技术。以下是一些常见的视觉智能开放平台产品及其应用场景的概览。
|
6月前
|
移动开发 文字识别 算法
视觉智能开放平台产品使用合集之需要调用人脸搜索来进行人脸打卡业务,该如何操作
视觉智能开放平台是指提供一系列基于视觉识别技术的API和服务的平台,这些服务通常包括图像识别、人脸识别、物体检测、文字识别、场景理解等。企业或开发者可以通过调用这些API,快速将视觉智能功能集成到自己的应用或服务中,而无需从零开始研发相关算法和技术。以下是一些常见的视觉智能开放平台产品及其应用场景的概览。
|
6月前
|
编解码 文字识别 算法
视觉智能开放平台产品使用合集之导致不同时间的人脸搜索分数不一致的因素有哪些
视觉智能开放平台是指提供一系列基于视觉识别技术的API和服务的平台,这些服务通常包括图像识别、人脸识别、物体检测、文字识别、场景理解等。企业或开发者可以通过调用这些API,快速将视觉智能功能集成到自己的应用或服务中,而无需从零开始研发相关算法和技术。以下是一些常见的视觉智能开放平台产品及其应用场景的概览。
|
6月前
|
文字识别 算法 API
视觉智能开放平台产品使用合集之人脸搜索1:N关于人脸图片的限制有哪些
视觉智能开放平台是指提供一系列基于视觉识别技术的API和服务的平台,这些服务通常包括图像识别、人脸识别、物体检测、文字识别、场景理解等。企业或开发者可以通过调用这些API,快速将视觉智能功能集成到自己的应用或服务中,而无需从零开始研发相关算法和技术。以下是一些常见的视觉智能开放平台产品及其应用场景的概览。