利用Java通过阿里云对图片进行内容审核

怎样用阿里云对图片进行内容审核

背景

随着互联网的发展,每个人都在网络上留下了自己的痕迹,在享受网络带来的便利的同时,去维护干净的网络环境也至关重要;目前在网络上会流动数亿的图片,显然使用纯手工去辨别是行不通的,所以如何用服务商提供的服务进行远程在线审核内容呢;现在很多公司都提供云服务,如阿里云就利用深度学习、机器学习搭建了内容审核系统,显示快速、高效地审核内容。

那作为使用方怎样去使用阿里云的图片审核服务呢?

首先要申请相关的秘钥
@Value("${aliyun.access_key_id}")
String ALIYUN_ACCESS_KEY_ID;
@Value("${aliyun.access_key_secret}")
String ALIYUN_ACCESS_KEY_SECRET;
@Value("${aliyun.region_id}")
String REGION_ID;

图片的自动审核,可以选定多个场景,如pornadterrorism

httpBody.put("scenes", Arrays.asList("porn", "terrorism", "ad"));

经过处理可以输出多个场景下审核结果,block:涉嫌违反,应当阻止,review:需要人工审核,pass:图片审核通过。

单张图片的审核
public void ascImage(String imageUrl) {

    IClientProfile profile = DefaultProfile.getProfile(REGION_ID, ALIYUN_ACCESS_KEY_ID, ALIYUN_ACCESS_KEY_SECRET);
    IAcsClient client = new DefaultAcsClient(profile);
    log.info("REGION_ID:{}, ALIYUN_ACCESS_KEY_ID:{},ALIYUN_ACCESS_KEY_SECRET:{} ", REGION_ID, ALIYUN_ACCESS_KEY_ID, ALIYUN_ACCESS_KEY_SECRET);

    ImageSyncScanRequest imageSyncScanRequest = new ImageSyncScanRequest();
    // 指定API返回格式。
    imageSyncScanRequest.setAcceptFormat(FormatType.JSON);
    // 指定请求方法。
    imageSyncScanRequest.setMethod(MethodType.POST);
    imageSyncScanRequest.setEncoding("utf-8");
    // 支持HTTP和HTTPS。
    imageSyncScanRequest.setProtocol(ProtocolType.HTTP);


    JSONObject httpBody = new JSONObject();
    /*
     * 设置要检测的风险场景。计费依据此处传递的场景计算。
     * 一次请求中可以同时检测多张图片,每张图片可以同时检测多个风险场景,计费按照场景计算。
     * 例如,检测2张图片,场景传递porn和terrorism,计费会按照2张图片鉴黄,2张图片暴恐检测计算。
     * porn:表示鉴黄场景。
     */
    httpBody.put("scenes", Arrays.asList("porn", "terrorism", "ad"));

    /**
     * 设置待检测图片。一张图片对应一个task。
     * 多张图片同时检测时,处理的时间由最后一个处理完的图片决定。
     * 通常情况下批量检测的平均响应时间比单张检测的要长。一次批量提交的图片数越多,响应时间被拉长的概率越高。
     * 这里以单张图片检测作为示例, 如果是批量图片检测,请自行构建多个task。
     */
    List<JSONObject> tasks = new ArrayList<>();
    // 构建了多张图片

    JSONObject task = new JSONObject();
    task.put("dataId", UUID.randomUUID().toString());
    // 设置图片链接。
    task.put("url", imageUrl);
    task.put("time", new Date());
    tasks.add(task);
    
    httpBody.put("tasks", tasks);

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

   /**
     * 请设置超时时间。服务端全链路处理超时时间为10秒,请做相应设置。
     * 如果您设置的ReadTimeout小于服务端处理的时间,程序中会获得一个ReadTimeout异常。
     */
    imageSyncScanRequest.setConnectTimeout(3000);
    imageSyncScanRequest.setReadTimeout(10000);
    HttpResponse httpResponse = null;
    try {
        httpResponse = client.doAction(imageSyncScanRequest);
    } catch (Exception e) {
        e.printStackTrace();
    }
    AcsImageResp acsImageResp = new AcsImageResp();
    // 服务端接收到请求,完成处理后返回的结果。
    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");
        // 每一张图片的检测结果。
        JSONArray taskResults = scrResponse.getJSONArray("data");

        log.info("taskResults: {}", taskResults);


        if (200 == requestCode) {
            for (Object taskResult : taskResults) {
                // 单张图片的处理结果。
                int taskCode = ((JSONObject) taskResult).getIntValue("code");
                String dataId = ((JSONObject) taskResult).getString("dataId");
                // 图片对应检测场景的处理结果。如果是多个场景,则会有每个场景的结果。
                JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
                if (200 == taskCode) {

                    ArrayList<Map> sceneSuggestions = new ArrayList<>();


                    for (Object sceneResult : sceneResults) {

                        String scene = ((JSONObject) sceneResult).getString("scene");
                        String suggestion = ((JSONObject) sceneResult).getString("suggestion");
                        String rate = ((JSONObject) sceneResult).getString("rate");

                        // 根据scene和suggestion做相关处理。
                        // 根据不同的suggestion结果做业务上的不同处理。例如,将违规数据删除等。
//                        System.out.println("scene = [" + scene + "]");
//                        System.out.println("suggestion = [" + suggestion + "]");


                    }

                } else {
                        // 单张图片处理失败, 原因视具体的情况详细分析。
                    log.info("task process fail. task response:" + JSON.toJSONString(taskResult));
                }

            }
        } else {
                /**
                 * 表明请求整体处理失败,原因视具体的情况详细分析。
                 */
            log.info("the whole image scan request failed. response:" + JSON.toJSONString(scrResponse));
        }
    }
}

上面的代码展示了如何对单张图片进审核,那在我们的日常生活中,比如发朋友圈、微博等很常见是需要对多张图片进行审核。那就需要对上面的代码进行升级。

实现对多张图片进行审核

首先输入参数需要进行封装,包含多个图片。

public void ascImage(AcsImageRequest acsImageRequest) {

    IClientProfile profile = DefaultProfile.getProfile(REGION_ID, ALIYUN_ACCESS_KEY_ID, ALIYUN_ACCESS_KEY_SECRET);
    IAcsClient client = new DefaultAcsClient(profile);
    log.info("REGION_ID:{}, ALIYUN_ACCESS_KEY_ID:{},ALIYUN_ACCESS_KEY_SECRET:{} ", REGION_ID, ALIYUN_ACCESS_KEY_ID, ALIYUN_ACCESS_KEY_SECRET);

    ImageSyncScanRequest imageSyncScanRequest = new ImageSyncScanRequest();
    // 指定API返回格式。
    imageSyncScanRequest.setAcceptFormat(FormatType.JSON);
    // 指定请求方法。
    imageSyncScanRequest.setMethod(MethodType.POST);
    imageSyncScanRequest.setEncoding("utf-8");
    // 支持HTTP和HTTPS。
    imageSyncScanRequest.setProtocol(ProtocolType.HTTP);


    JSONObject httpBody = new JSONObject();
    /*
     * 设置要检测的风险场景。计费依据此处传递的场景计算。
     * 一次请求中可以同时检测多张图片,每张图片可以同时检测多个风险场景,计费按照场景计算。
     * 例如,检测2张图片,场景传递porn和terrorism,计费会按照2张图片鉴黄,2张图片暴恐检测计算。
     * porn:表示鉴黄场景。
     */
    httpBody.put("scenes", Arrays.asList("porn", "terrorism", "ad"));

    /**
     * 设置待检测图片。一张图片对应一个task。
     * 多张图片同时检测时,处理的时间由最后一个处理完的图片决定。
     * 通常情况下批量检测的平均响应时间比单张检测的要长。一次批量提交的图片数越多,响应时间被拉长的概率越高。
     * 这里以单张图片检测作为示例, 如果是批量图片检测,请自行构建多个task。
     */
    List<JSONObject> tasks = new ArrayList<>();
    // 构建了多张图片 TODO
    for (int i = 0; i < acsImageRequest.getImageList().size(); i++) {
        JSONObject task = new JSONObject();
        task.put("dataId", UUID.randomUUID().toString());
        // 设置图片链接。
        task.put("url", acsImageRequest.getImageList().get(i).getImageUrl());
        task.put("time", new Date());
        tasks.add(task);
     }

     //多张图片
     httpBody.put("tasks", tasks);

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

   /**
     * 请设置超时时间。服务端全链路处理超时时间为10秒,请做相应设置。
     * 如果您设置的ReadTimeout小于服务端处理的时间,程序中会获得一个ReadTimeout异常。
     */
    imageSyncScanRequest.setConnectTimeout(3000);
    imageSyncScanRequest.setReadTimeout(10000);
    HttpResponse httpResponse = null;
    try {
        httpResponse = client.doAction(imageSyncScanRequest);
    } catch (Exception e) {
        e.printStackTrace();
    }
    AcsImageResp acsImageResp = new AcsImageResp();
    // 服务端接收到请求,完成处理后返回的结果。
    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");
        // 每一张图片的检测结果。
        JSONArray taskResults = scrResponse.getJSONArray("data");

        log.info("taskResults: {}", taskResults);


        if (200 == requestCode) {
            for (Object taskResult : taskResults) {
                // 单张图片的处理结果。
                int taskCode = ((JSONObject) taskResult).getIntValue("code");
                String dataId = ((JSONObject) taskResult).getString("dataId");
                // 图片对应检测场景的处理结果。如果是多个场景,则会有每个场景的结果。
                JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
                if (200 == taskCode) {

                    ArrayList<Map> sceneSuggestions = new ArrayList<>();


                    for (Object sceneResult : sceneResults) {

                        String scene = ((JSONObject) sceneResult).getString("scene");
                        String suggestion = ((JSONObject) sceneResult).getString("suggestion");
                        String rate = ((JSONObject) sceneResult).getString("rate");

                        // 根据scene和suggestion做相关处理。
                        // 根据不同的suggestion结果做业务上的不同处理。例如,将违规数据删除等。
//                        System.out.println("scene = [" + scene + "]");
//                        System.out.println("suggestion = [" + suggestion + "]");


                    }

                } else {
                        // 单张图片处理失败, 原因视具体的情况详细分析。
                    log.info("task process fail. task response:" + JSON.toJSONString(taskResult));
                }

            }
        } else {
                /**
                 * 表明请求整体处理失败,原因视具体的情况详细分析。
                 */
            log.info("the whole image scan request failed. response:" + JSON.toJSONString(scrResponse));
        }
    }
}
如上建立多个task即可。
for (int i = 0; i < acsImageRequest.getImageList().size(); i++) {
    JSONObject task = new JSONObject();
    task.put("dataId", UUID.randomUUID().toString());
    // 设置图片链接。
    task.put("url", acsImageRequest.getImageList().get(i).getImageUrl());
    task.put("time", new Date());
    tasks.add(task);
}
多张图片处理的结果如下:
{
        "msg":"OK",
        "code":200,
        "data":[
                {
                        "msg":"OK",
                        "code":200,
                        "dataId":"8c728368-c872-4fb1-8b48-9bd186278715",
                        "extras":{},
                        "results":[
                                {
                                        "rate":98.99979,
                                        "suggestion":"block",
                                        "label":"porn",
                                        "scene":"porn"
                                },
                                {
                                        "rate":100.0,
                                        "suggestion":"pass",
                                        "label":"normal",
                                        "scene":"terrorism"
                                },
                                {
                                        "rate":99.91,
                                        "suggestion":"pass",
                                        "label":"normal",
                                        "scene":"ad"
                                }
                        ],
                        "taskId":"img3PAU2TEmQ995bJU4oJGV7V-1vPqcl",
                        "url":"https://www.zihufsamei.com/office/uplfsoad/comzhm28402zhm2018112fjdsjlf14145218790.jpg"
                },
                {
                        "msg":"OK",
                        "code":200,
                        "dataId":"06be3693-d2c8-41a3-9f65-308730a632de",
                        "extras":{},
                        "results":[
                                {
                                        "rate":98.99979,
                                        "suggestion":"block",
                                        "label":"porn",
                                        "scene":"porn"
                                },
                                {
                                        "rate":100.0,
                                        "suggestion":"pass",
                                        "label":"normal",
                                        "scene":"terrorism"
                                },
                                {
                                        "rate":99.91,
                                        "suggestion":"pass",
                                        "label":"normal",
                                        "scene":"ad"
                                }
                        ],
                        "taskId":"imgrNIkr@IA@a6qTGj0vBgLb-1vPqcl",
                        "url":"https://www.zihufddamei.com/office/uploadfhsafshj/comzhm28402zhm201811214145218790.jpg"
                }
        ],
        "requestId":"AEE070FA-B8F5-5999-889D-2B45D24BDD05"
}

最后阿里云帮我们判断每张图片是否违规之后,那我们拿到这些结果之后应该做如何处理呢?

这里需要明白的逻辑:
  • 如果有一张图片的suggestionblock,那么整个处理就应该是block
  • 如果没有block,那么里面有一张是review的话,那么整个处理应该是review
  • 只有全部是pass,整个多张图片的处理才是pass
根据上面的逻辑编写下面的处理逻辑:
//根据多个场景进行判断
public Map sceneJudge(List<Map> maps) {
    for (int i = 0; i < maps.size(); i++) {
        if (maps.get(i).get("suggestion").equals("block")) {
            return maps.get(i);
        }
    }
    for (int i = 0; i < maps.size(); i++) {
        if (maps.get(i).get("suggestion").equals("review")) {
            return maps.get(i);
        }
    }
    return maps.get(0);
}
// 根据每张图片进行判断
public Map imageJudge(List<Map> maps) {
    for (int i = 0; i < maps.size(); i++) {
        if (maps.get(i).get("suggestion").equals("block")) {
            return maps.get(i);
        }
    }

    for (int i = 0; i < maps.size(); i++) {
        if (maps.get(i).get("suggestion").equals("review")) {
            return maps.get(i);
        }
    }
    return maps.get(0);
}
为了能使用上如上的逻辑,需要对审核的结果进行存储,对多张图片的审核代码进行了添加。
for (Object sceneResult : sceneResults) {
    // 保存每张图片的各个场景结果
    HashMap<String, String> map = new HashMap<>();

    String scene = ((JSONObject) sceneResult).getString("scene");
    String suggestion = ((JSONObject) sceneResult).getString("suggestion");
    String rate = ((JSONObject) sceneResult).getString("rate");

    // 根据scene和suggestion做相关处理。
    // 根据不同的suggestion结果做业务上的不同处理。例如,将违规数据删除等。
//  System.out.println("scene = [" + scene + "]");
//                            System.out.println("suggestion = [" + suggestion + "]");

    map.put("scene", scene);
    map.put("suggestion", suggestion);
    map.put("rate", rate);

    sceneSuggestions.add(map);
}
接着对sceneSuggesitons进行处理,实现从多个维度实现单张图片的判断。
Map sceneJudgeResult = sceneJudge(sceneSuggestions);
imageJudgeList.add(sceneJudgeResult);
接着对imageJudgeList进行处理,实现对多张图片的判断。
Map imageJudgeResult = imageJudge(imageJudgeList);
最后可以实现对多张图片审核结果的封装和返回
acsImageResp.setSuggestion((String) imageJudgeResult.get("suggestion"));
acsImageResp.setRate((String) imageJudgeResult.get("rate"));

return acsImageResp;
最后的返回的结果
AcsImageResp(suc
cess=true, suggestion=block, rate=98.99979, uuid=769c8be6-5ff9-44a9-b9ba-6a95edcfdb66, details={"msg":"OK","code":200,"data":[{"msg":"OK","
code":200,"dataId":"8c728368-c872-4fb1-8b48-9bd186278715","extras":{},"results":[{"rate":98.99979,"suggestion":"block","label":"porn","scen
e":"porn"},{"rate":100.0,"suggestion":"pass","label":"normal","scene":"terrorism"},{"rate":99.91,"suggestion":"pass","label":"normal","scen
e":"ad"}],"taskId":"img3PAU2TEmQ995bJU4oJGV7V-1vPqcl","url":"https://www.zihuagfsdmei.com/office/upload/comzhm28402zhm201811214145218790.jpg"},
{"msg":"OK","code":200,"dataId":"06be3693-d2c8-41a3-9f65-308730a632de","extras":{},"results":[{"rate":98.99979,"suggestion":"block","label"
:"porn","scene":"porn"},{"rate":100.0,"suggestion":"pass","label":"normal","scene":"terrorism"},{"rate":99.91,"suggestion":"pass","label":"
normal","scene":"ad"}],"taskId":"imgrNIkr@IA@a6qTGj0vBgLb-1vPqcl","url":"https://www.zihuamgdfei.com/office/upload/comzhm28402zhm2018112141452
18790.jpg"}],"requestId":"AEE070FA-B8F5-5999-889D-2B45D24BDD05"})

你可能感兴趣的:(Spring,阿里云,云计算,java,图片审核)