天天看點

阿裡雲人臉搜尋最佳實踐

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