Face comparison

Updated at:

Use the Content Moderation Java SDK to compare two face images and determine their similarity. The SDK returns a suggestion value indicating whether the faces match.

  • Synchronous moderation: results are returned in real time. For supported parameters, see Synchronous moderation.

  • Asynchronous moderation: poll for results or configure a callback notification to receive them. For supported parameters, see Asynchronous moderation.

How it works

  1. Build a request body with the sface-1 scene and two face image references: the primary image URL in task.url and the comparison image URL in task.extras.faceUrl.

  2. Submit a synchronous scan request to green.cn-shanghai.aliyuncs.com using ImageSyncScanRequest.

  3. Parse the response: check the top-level code for overall request status, then iterate data for per-image results and results for per-scene suggestion values.

Prerequisites

Before you begin, ensure that you have:

  • Java dependencies installed. See Installation and use the exact Java version specified there — other versions cause operation call failures.

  • (Required for local file upload) The Extension.Uploader utility class downloaded and imported into your project.

Submit face image URLs

All examples use ImageSyncScanRequest to submit a synchronous face comparison request. The two face images are passed as task.url (image 1) and task.extras.faceUrl (image 2).

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.green.extension.uploader.ClientUploader;
import com.aliyuncs.green.model.v20180509.ImageSyncScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;

import java.util.*;

public class ImageSyncScanSample {

    public static void main(String[] args) throws Exception {
        /**
         * Use a RAM user's AccessKey pair instead of your Alibaba Cloud account credentials.
         * Load credentials from environment variables to avoid hardcoding sensitive values.
         *
         * Method 1 (environment variables):
         *     System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
         *     System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
         * Method 2 (system properties):
         *     System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_ID")
         *     System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
         */
        DefaultProfile profile = DefaultProfile.getProfile(
                "cn-shanghai",
                System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");

        // Reuse the client across requests to improve performance and avoid repeated connections.
        IAcsClient client = new DefaultAcsClient(profile);

        ImageSyncScanRequest imageSyncScanRequest = new ImageSyncScanRequest();
        imageSyncScanRequest.setAcceptFormat(FormatType.JSON);
        imageSyncScanRequest.setMethod(MethodType.POST);
        imageSyncScanRequest.setEncoding("utf-8");
        imageSyncScanRequest.setProtocol(ProtocolType.HTTP);

        JSONObject httpBody = new JSONObject();
        httpBody.put("scenes", Arrays.asList("sface-1"));

        JSONObject task = new JSONObject();
        // Face image 1: the primary image URL.
        task.put("url", "http://example.com/xxx.jpg");
        JSONObject extras = new JSONObject();
        // Face image 2: the comparison image URL.
        extras.put("faceUrl", "http://example.com/yyyy.jpg");
        task.put("extras", extras);
        httpBody.put("tasks", Arrays.asList(task));

        imageSyncScanRequest.setHttpContent(
                org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()),
                "UTF-8", FormatType.JSON);

        /**
         * The server requires up to 10 seconds to complete a moderation request.
         * Set the read timeout to at least 10,000 ms to avoid read timeout errors.
         */
        imageSyncScanRequest.setConnectTimeout(3000);
        imageSyncScanRequest.setReadTimeout(10000);

        HttpResponse httpResponse = null;
        try {
            httpResponse = client.doAction(imageSyncScanRequest);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (httpResponse != null && httpResponse.isSuccess()) {
            JSONObject scrResponse = JSON.parseObject(
                    org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
            System.out.println(JSON.toJSONString(scrResponse, true));

            int requestCode = scrResponse.getIntValue("code");
            // Moderation results for all submitted images.
            JSONArray taskResults = scrResponse.getJSONArray("data");
            if (200 == requestCode) {
                for (Object taskResult : taskResults) {
                    // Result for a single image.
                    int taskCode = ((JSONObject) taskResult).getIntValue("code");
                    // Per-scene results. If you specified multiple scenes, one entry is returned per scene.
                    JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
                    if (200 == taskCode) {
                        for (Object sceneResult : sceneResults) {
                            String scene = ((JSONObject) sceneResult).getString("scene");
                            String suggestion = ((JSONObject) sceneResult).getString("suggestion");
                            // Act on the scene and suggestion values.
                            System.out.println("suggestion = [" + suggestion + "]");
                        }
                    } else {
                        // Moderation failed for this image. Investigate based on the response details.
                        System.out.println("task process fail. task response:" + JSON.toJSONString(taskResult));
                    }
                }
            } else {
                // The overall request failed. Investigate based on the response details.
                System.out.println("the whole image scan request failed. response:" + JSON.toJSONString(scrResponse));
            }
        }
    }

}

Submit local files

Use ClientUploader to upload local image files before comparison. Both face images are uploaded and their returned URLs are passed to task.url and task.extras.faceUrl.

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.green.extension.uploader.ClientUploader;
import com.aliyuncs.green.model.v20180509.ImageSyncScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;

import java.util.*;

public class ImageSyncScanSample {

    public static void main(String[] args) throws Exception {
        /**
         * Use a RAM user's AccessKey pair instead of your Alibaba Cloud account credentials.
         * Load credentials from environment variables to avoid hardcoding sensitive values.
         *
         * Method 1 (environment variables):
         *     System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
         *     System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
         * Method 2 (system properties):
         *     System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_ID")
         *     System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
         */
        DefaultProfile profile = DefaultProfile.getProfile(
                "cn-shanghai",
                System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");

        // Reuse the client across requests to improve performance and avoid repeated connections.
        IAcsClient client = new DefaultAcsClient(profile);

        ImageSyncScanRequest imageSyncScanRequest = new ImageSyncScanRequest();
        imageSyncScanRequest.setAcceptFormat(FormatType.JSON);
        imageSyncScanRequest.setMethod(MethodType.POST);
        imageSyncScanRequest.setEncoding("utf-8");
        imageSyncScanRequest.setProtocol(ProtocolType.HTTP);

        JSONObject httpBody = new JSONObject();
        httpBody.put("scenes", Arrays.asList("sface-1"));

        ClientUploader clientUploader = ClientUploader.getImageClientUploader(profile, false);

        JSONObject task = new JSONObject();

        // Upload face image 1 and use the returned URL as the primary image.
        String url1 = null;
        try {
            url1 = clientUploader.uploadFile("d:/image1.jpg");
        } catch (Exception e) {
            e.printStackTrace();
        }
        task.put("url", url1);

        JSONObject extras = new JSONObject();
        // Upload face image 2 and use the returned URL as the comparison image.
        String url2 = null;
        try {
            url2 = clientUploader.uploadFile("d:/image2.jpg");
        } catch (Exception e) {
            e.printStackTrace();
        }
        extras.put("faceUrl", url2);
        task.put("extras", extras);
        httpBody.put("tasks", Arrays.asList(task));

        imageSyncScanRequest.setHttpContent(
                org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()),
                "UTF-8", FormatType.JSON);

        /**
         * The server requires up to 10 seconds to complete a moderation request.
         * Set the read timeout to at least 10,000 ms to avoid read timeout errors.
         */
        imageSyncScanRequest.setConnectTimeout(3000);
        imageSyncScanRequest.setReadTimeout(10000);

        HttpResponse httpResponse = null;
        try {
            httpResponse = client.doAction(imageSyncScanRequest);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (httpResponse != null && httpResponse.isSuccess()) {
            JSONObject scrResponse = JSON.parseObject(
                    org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
            System.out.println(JSON.toJSONString(scrResponse, true));

            int requestCode = scrResponse.getIntValue("code");
            // Moderation results for all submitted images.
            JSONArray taskResults = scrResponse.getJSONArray("data");
            if (200 == requestCode) {
                for (Object taskResult : taskResults) {
                    // Result for a single image.
                    int taskCode = ((JSONObject) taskResult).getIntValue("code");
                    // Per-scene results. If you specified multiple scenes, one entry is returned per scene.
                    JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
                    if (200 == taskCode) {
                        for (Object sceneResult : sceneResults) {
                            String scene = ((JSONObject) sceneResult).getString("scene");
                            String suggestion = ((JSONObject) sceneResult).getString("suggestion");
                            // Act on the scene and suggestion values.
                            System.out.println("suggestion = [" + suggestion + "]");
                        }
                    } else {
                        // Moderation failed for this image. Investigate based on the response details.
                        System.out.println("task process fail. task response:" + JSON.toJSONString(taskResult));
                    }
                }
            } else {
                // The overall request failed. Investigate based on the response details.
                System.out.println("the whole image scan request failed. response:" + JSON.toJSONString(scrResponse));
            }
        }
    }

}

What's next