随着互联网的发展,每个人都在网络上留下了自己的痕迹,在享受网络带来的便利的同时,去维护干净的网络环境也至关重要;目前在网络上会流动数亿的图片,显然使用纯手工去辨别是行不通的,所以如何用服务商提供的服务进行远程在线审核内容呢;现在很多公司都提供云服务,如阿里云就利用深度学习、机器学习搭建了内容审核系统,显示快速、高效地审核内容。
@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;
图片的自动审核,可以选定多个场景,如porn
、ad
,terrorism
。
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));
}
}
}
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"
}
最后阿里云帮我们判断每张图片是否违规之后,那我们拿到这些结果之后应该做如何处理呢?
suggestion
是block
,那么整个处理就应该是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"})