使用函数计算实现OSS图片增量检测

如果需要实时检测上传到OSS Bucket的图片是否存在违规内容,且根据检测结果决定如何处理图片,例如是否对外公开、转存后人工复核等问题,可以通过函数计算调用内容安全的图片审核增强版服务。本文介绍如何使用函数计算实现OSS Bucket增量图片数据的检测。

方案架构

函数计算.png

方案优势

与内容安全OSS违规检测1.0版本功能相比,使用函数计算的方案具备如下优势:

  • 支持配置多个函数以实现不同OSS Bucket采用不同的检测配置。

  • 检测日志写入日志服务SLS对应的Project中,更方便查询和分析检测结果。

  • 函数计算对事件和请求能实时动态伸缩,实现增量图片检测能力接近毫秒级。

  • 虚拟机级别隔离运行,更灵活也更安全地处理OSS Bucket文件。

说明

如需定期或者批量检测OSS Bucket图片数据,请参见批量检测OSS存储图片数据

费用说明

使用函数计算实现OSS Bucket增量图片数据的检测,会产生以下几部分费用:

类别

说明

内容审核服务费用

调用图片审核增强版API服务的费用。具体信息,请参见图片审核增强版介绍及计费说明

OSS访问和流量费用

访问OSS Bucket文件过程会产生请求费用。具体信息,请参见请求费用

同地域下调用审核API使用OSS内网地址为内网流量传输,跨地域或者调用审核API使用公网地址会产生外网流量费用。具体信息,请参见流量费用

函数计算调用和资源费用

使用函数计算触发OSS事件并调用函数会产生相应的资源和调用费用。具体信息,请参见计费概述

图片审核增强版服务支持接入的地域

地域

外网接入地址

内网接入地址

华东2(上海)

green-cip.cn-shanghai.aliyuncs.com

green-cip-vpc.cn-shanghai.aliyuncs.com

华北2(北京)

green-cip.cn-beijing.aliyuncs.com

green-cip-vpc.cn-beijing.aliyuncs.com

华东1(杭州)

green-cip.cn-hangzhou.aliyuncs.com

green-cip-vpc.cn-hangzhou.aliyuncs.com

华南1(深圳)

green-cip.cn-shenzhen.aliyuncs.com

暂无

西南1(成都)

green-cip.cn-chengdu.aliyuncs.com

暂无

新加坡

green-cip.ap-southeast-1.aliyuncs.com

green-cip-vpc.ap-southeast-1.aliyuncs.com

前提条件

操作步骤

  1. 登录函数计算控制台,选择服务地域,创建服务和函数。具体操作,请参见管理服务管理函数

    创建函数时,选择使用内置运行时创建的方式,核心字段配置如下:

    • 基本设置区域,选择请求处理程序类型处理事件请求

      image.png
    • 函数代码区域,根据实际业务选择运行环境,设置代码上传方式使用示例代码方式,并选择对象存储OSS触发函数

      image.png
    • 触发器配置区域,选择触发器类型对象存储OSS,指定Bucket名称osstest-20文件前缀img文件后缀png触发事件选择oss:ObjectCreated:PutObjectoss:ObjectCreated:PostObject事件,角色名称AliyunOSSEventNotificationRole

      首次创建函数时,您可以根据页面提示授予事件源访问函数计算权限。更多内容,请参见授予事件源访问函数计算的权限

      关于OSS触发器事件的详细信息,请参见OSS触发器概述

      image.png
  2. 通过函数调用内容安全图片审核增强版服务。

    创建函数后会跳转到函数代码界面,在编辑器页面中即可编辑调用内容安全的示例代码。详细参数说明,请参见图片审核增强版API

    关于函数代码编辑介绍,请参见代码开发概述

    以下为您展示图片审核增强版Python代码示例。在调用以下代码示例前,您需要先将AccessKey ID和AccessKey Secret写入到配置文件config.ini中。

    # -*- coding: utf-8 -*-
    import json, uuid
    import configparser
    from aliyunsdkcore.client import AcsClient
    from aliyunsdkcore.request import CommonRequest
    def handler(event, context):
        config = configparser.ConfigParser()
        config.read("config.ini", encoding="GB18030")
        # AccessKey ID和AccessKey Secret写入的配置文件。
        evt = json.loads(event)
        evt = evt['events'][0]
        bucket_name = evt['oss']['bucket']['name']
        object_name = evt['oss']['object']['key']
        
        # 公网地址,需要公共读且会产生OSS公网流量费用。
        objecturl = "https://" + bucket_name + ".oss-cn-hangzhou.aliyuncs.com/" + object_name
        client = AcsClient(config.get("config", "accessKeyId"), config.get("config", "accessSecret"), 'cn-shanghai')
        request = CommonRequest()
        request.set_read_timeout(6000)  # 读取超时时间配置。
        request.set_connect_timeout(3000)  # 连接超时时间配置。
        request.set_accept_format('json')
        request.set_method('POST')
        request.set_protocol_type('https')  # https | http
        request.set_domain('green-cip.cn-shanghai.aliyuncs.com')
        request.set_version('2022-03-02')
        request.set_action_name('ImageModeration')
        
        request.add_query_param("Service", "baselineCheck")
        request.add_query_param("ServiceParameters",
                                {
                                    'imageUrl': objecturl,
                                    'dataId': str(uuid.uuid4())
                                })
        
        response = client.do_action_with_exception(request)
        print(str(response, encoding='utf-8'))
        
        response_json = json.loads(response)
        if response_json.get("Code") == 200:
            for item in response_json.get("Data", {}).get("Result", []):
                if item["Label"] == "nonLabel":
                    print("nonLabel 无命中标签")
                elif "pornographic" in item["Label"] and int(item["Confidence"]) > 80:
                    print("疑似含有色情内容")
                elif "political" in item["Label"] and int(item["Confidence"]) > 80:
                    print("疑似含有涉政内容")
                elif "violent" in item["Label"] and int(item["Confidence"]) > 80:
                    print("疑似含有暴恐内容")
                elif "fraud" in item["Label"] and int(item["Confidence"]) > 80:
                    print("疑似含有风险内容")
        else:
            print("请求失败,错误码:", response_json.get("Code"))

    如果是华东2(cn-shanghai)或者华北2(cn-beijing)区域的OSS图片,支持使用OSS图片内网地址调用同区域的审核服务。使用前须使用阿里云账号(即主账号)访问云资源访问授权页面进行授权。更详细的参数信息,请参考图片审核增强版API

    # -*- coding: utf-8 -*-
    import json, uuid
    import configparser
    from aliyunsdkcore.client import AcsClient
    from aliyunsdkcore.request import CommonRequest
    def handler(event, context):
        config = configparser.ConfigParser()
        config.read("config.ini", encoding="GB18030")
        # AccessKey ID和AccessKey Secret写入的配置文件。
        evt = json.loads(event)
        evt = evt['events'][0]
        bucket_name = evt['oss']['bucket']['name']
        object_name = evt['oss']['object']['key']
    
        client = AcsClient(config.get("config", "accessKeyId"), config.get("config", "accessSecret"), 'cn-shanghai')
        request = CommonRequest()
        request.set_read_timeout(6000)  # 读取超时时间配置。
        request.set_connect_timeout(3000)  # 连接超时时间配置。
        request.set_accept_format('json')
        request.set_method('POST')
        request.set_protocol_type('https')  # https | http
        request.set_domain('green-cip.cn-shanghai.aliyuncs.com')
        request.set_version('2022-03-02')
        request.set_action_name('ImageModeration')
        
        request.add_query_param("Service", "baselineCheck")
        request.add_query_param("ServiceParameters",
                                {
                                    'ossRegionId': 'cn-shanghai',
                                    'ossBucketName': bucket_name,
                                    'ossObjectName': object_name,
                                    'dataId': str(uuid.uuid4())
                                })
        
        response = client.do_action_with_exception(request)
        print(str(response, encoding='utf-8'))
        
        response_json = json.loads(response)
        if response_json.get("Code") == 200:
            for item in response_json.get("Data", {}).get("Result", []):
                if item["Label"] == "nonLabel":
                    print("nonLabel 无命中标签")
                elif "pornographic" in item["Label"] and int(item["Confidence"]) > 80:
                    print("疑似含有色情内容")
                elif "political" in item["Label"] and int(item["Confidence"]) > 80:
                    print("疑似含有涉政内容")
                elif "violent" in item["Label"] and int(item["Confidence"]) > 80:
                    print("疑似含有暴恐内容")
                elif "fraud" in item["Label"] and int(item["Confidence"]) > 80:
                    print("疑似含有风险内容")
        else:
            print("请求失败,错误码:", response_json.get("Code"))
  3. 进行图片增量检测。

    通过OSS PostObject或者OSS PutObject接口上传图片文件时,即可触发该函数执行。检测完成后,您可以在调用日志中查看检测结果。具体操作,请参见查看调用日志

    image.png

    如果您需要进一步处理OSS文件,比如冻结或者删除文件等操作,请参见管理文件