python调用腾讯云识别图片标签 python调用腾讯优图识别图片

一、需求描述

需要识别图片给图片打上标签,比如:图片里面有杨幂,就是美女标签

最开始准备用免费的腾讯优图API,但是鼓捣了两天怎么也搞不定,根据官方文档来操作应该是不能用,放弃了,下面会详细介绍坑点

后来试的百度AI开放平台的识别,发现页面总是卡死,效果也不太准确

最后用的腾讯云,发现是真他妈的香,满足你的一切幻想

二、腾讯优图踩坑过程

>>腾讯优图<<图片识别是免费的,一开始本打算用这个的,但是发现用不了,折腾了两天,各种尝试,以为自己代码没写好,直到看到了他的SDK源码,我放弃了 

2.1 自己生成签名

首先体验界面就这样显示......

 

 开发步骤:

 

 >>签名生成<<:

签名的生成过程,只有下图这么多,没有详细的描述,没有可靠的的代码demo

 

 按照文档,我自己生成了个签名,并且去请求,返回403,禁止访问,不清楚是签名的问题还是后台维护的问题,感觉应该是后台的问题,代码见下:

"""
需求:识别图片内容为之打上标签,图片包含url形式的和image形式的

实现思路:python调用腾讯优图api,参考腾讯官方文档:https://open.youtu.qq.com/#/open/developer/join
1.按照新手指引-免费接入优图AI开放平台 申请公有云,获取appid、SecretID、SecretKey
2.生成签名:https://open.youtu.qq.com/#/develop/tool-authentication/auth

步骤:调用api需要配置header请求头,请求头需要鉴权签名,鉴权签名需要api密钥。

鉴权签名:https://cloud.tencent.com/document/product/866/17734

api密钥的获取:登陆腾讯云https://console.cloud.tencent.com/cam/capi

代码如下

"""

import time
import base64
import hmac
import hashlib
import binascii
import hmac
import requests
import json
import datetime
import random
from sys import getsizeof


'''第一步:通过腾讯优图申请公有云获取自己的api密钥++++++++++++++++++++++++++++
'''
qq = '13++++QQ+++1'
appid='1+++++4'
SecretID='AKID++++++++++f39zY'
SecretKey=' Zrt+++++++++++++++DK'

'''第二步:生成签名 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'''

# (1)拼接有效字符串
u = qq # 开发者创建应用时的QQ号
a = appid
k = SecretID
t = int(time.time()) #当前时间戳
e = t + 2592000 #签名的有效期 此处定义为当前时间+30天
r = random.randint(0, 999999999) #随机串,最长10位
f = ''
original = f"{u}=10000&{a}=2011541224&{k}=AKID2ZkOXFyDRHZRlbPo93SMtzVY79kpAdGP&{e}=1432970065&{t}=1427786065&{r}=270494647&{f}="

# (2)生成签名
def hash_hmac(secret_key,orignal):
    """生成签名的函数
    """
    # 对orignal使用HMAC-SHA1算法进行签名
    SignTmp = hmac.new(bytes(secret_key,'utf-8'),bytes(orignal,'utf-8'), hashlib.sha1).digest()
    # 然后将orignal附加到签名结果的末尾,再进行Base64编码,得到最终的sign
    Sign = base64.b64encode(SignTmp+orignal.encode())
    print(Sign)
    return Sign

print(original)
authorization=hash_hmac(SecretKey,original)

"""第三步:使用+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    参考:https://open.youtu.qq.com/#/open/developer/image-label
"""

url='https://api.youtu.qq.com/youtu/imageapi/imagetag'
filepath = 'D:\\15859773d.png'
payload = {'image':base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8'),
           'app_id':appid,
           'seq':''}

Length = str(getsizeof(payload))

headers={
'Host':'api.youtu.qq.com', # 图片云服务器域名,固定为api.youtu.qq.com
'Content-Length':Length, # 整个请求包体内容的总长度,单位:字节(Byte)
'Content-Type':'text/json', #text/json表示json格式
'Authorization':authorization, # 多次有效签名,用于鉴权,以Authorization为key
}


r = requests.post(url,data = json.dumps(payload) ,headers=headers)
print(r)
print(r.content)

2.2 调用SDK

既然自己生成签名不行,那就调用>>现成的SDK<<吧,页面就这,没有写支持的版本...

SDK的使用也是个谜:

 

 一顿操作后我才发现,这个SDK还是个远古SDK,只支持python 2.x,好吧,emmmm......

既然不支持python3,那我就去源码里面把各种方法拿出来用,这些总该可以吧,然而,一顿操作后,我发现自己天真了:

-- 头部信息对不上:

 

 -- 基础拼接字符串也对不上:

 

 虽然各种对不上,但是手动生成的签名请求返回403,死马当活马医,试试SDK,将SDK中各个方法拿出来,用这里面的方法生成签名去请求,返回401,也不行

总结:腾讯优图实在有点坑,免费的果然。。。是免费的

代码见下:

import time
import base64
import hmac
import hashlib
import binascii
import hmac
import requests
import json
import datetime
import random
from sys import getsizeof


def app_sign(appid,SecretID,SecretKey,puserid):
    now = int(time.time())
    expired = 2592000  # 签名的有效期 此处定义为当前时间+30天
    rdm = random.randint(0, 999999999) #随机串,最长10位
    plain_text = 'a=' + appid + '&k=' + SecretID + '&e=' + str(expired) + '&t=' + str(now) + '&r=' + str(
        rdm) + '&u=' + puserid + '&f='
    bin = hmac.new(SecretKey.encode(), plain_text.encode(), hashlib.sha1)
    s = bin.hexdigest()
    s = binascii.unhexlify(s)
    s = s + plain_text.encode('ascii')
    signature = base64.b64encode(s).rstrip()  # 生成签名
    print(62,signature)
    return signature
    # 'EndITIThX1WqAkBfdPufvS9h7i9hPTEwMjcwMjk0Jms9QUtJRHVlN0tHdklPRW83OXZRZWJIaHFoSGFjTnI0MGYzOXpZJmU9MjU5MjAwMCZ0PTE2MjQ1MDQ0ODcmcj0yMTU2MjQ3ODkmdT0xMzE1NDU4NTcxJmY9'

'''第一步:通过腾讯优图申请公有云获取自己的api密钥++++++++++++++++++++++++++++
'''
qq = '1===============71'
appid='19899999999999999444'
SecretID='AK0000000000000000039zY'
SecretKey=' Z666666666666666666666DK'

'''第二步:生成签名 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'''
authorization = app_sign(appid=appid, SecretID=SecretID,SecretKey=SecretKey,puserid=qq)

"""第三步:使用+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    参考:https://open.youtu.qq.com/#/open/developer/image-label
"""
headers={
'Content-Type':'text/json', #text/json表示json格式
'Authorization':authorization, # 多次有效签名,用于鉴权,以Authorization为key
}

url='https://api.youtu.qq.com/youtu/imageapi/imagetag'
filepath = 'D:\\25a82978e15859773d.png'
payload = {'image':base64.b64encode(open(filepath, 'rb').read()).rstrip().decode('utf-8'),
           'app_id':appid,
           'seq':''}
r = requests.post(url,data = json.dumps(payload) ,headers=headers)
print(999,r)
print(999,r.content)

 

 

 

三、百度AI开放平台和腾讯云对比

首先这两个平台都是要收费的,价格不一,腾讯云有10000张免费额度

对比了一些图片,发现腾讯的更好用一些,更准确,并且签名什么的繁琐步骤直接给封装好的SDK支持大多数python版本,并且可以动态生成代码,详见下一节,下面展示结果:

百度识图: https://ai.baidu.com/tech/imagerecognition/object_detect

 腾讯云识别:

入口:腾讯云主页- 产品 - 人工智能 - 图像识别 - DEMO体验

 

 四、腾讯云 图片识别

腾讯云:https://cloud.tencent.com/

图片识别操作指引:   https://cloud.tencent.com/document/product/865/17630

腾讯云没人有10000张图片的免费额度,各个模块都有,但是应该是有有效期一个月的

腾讯云的用户体验不要太好了,你想要的他都有,除了收费,还是rmb玩家体验好,腾讯优图虽然免费,但是简直 emmm...

4.1 准备阶段和图片识别流程概述

- 登录账号

注册并通过实名认证后,您。如果没有账号,请参考 注册腾讯云教程 。

- 创建密钥

完成注册后,您需要在 访问管理控制台 创建密钥。AppID、SecretID 和 SecretKey 是您进行应用开发的唯一凭证,请务必妥善保管。

- 生成签名

通过签名来验证请求的合法性,您可以使用主账号的 AppID、SecretID 和 SecretKey 生成签名,具体签名生成方法请参阅 接口鉴权 。

这个签名算法可以自己实现,但是腾讯云已经提供了SDK,里面封装的有,签名这个步骤基本不需要考虑,参考下面 4.2 安装SDK调用就好了

4.2  了解API 和 SDK

我们为您提供了简单易用的 API 接口,您可以查看并调用 图像分析 。

可以直接进入 >> 图片标签<< 查看这个API的功能,了解输入参数、输出参数,然后直接找到下方的SDK:

云 API 3.0 提供了配套的开发工具集(SDK),支持多种编程语言,能更方便的调用 API,支持Python 2.7, 3.6-3.9 版本,见下:

SDK里面有详细的描述,支持pip安装,也支持下载安装,并且有非常清楚的注释版本的代码demo可供参考,该demo不是图像识别的的,整体代码框架一样,具体方法参数需要自己修改

4.3 图片识别开发代码

SDK里面给出的不是图像识别的代码,那么具体代码怎么调用书写呢?这时候就要用腾讯云的另一个超好用的功能:API Explorer

这个界面直接可以在线调用逐步演示签名生成过程,还有参数详细说明最主要的是可以实时生成代码太香了

 

 这个代码只需要自己复制走,稍微更改一下参数就好了,当然还有很多参数可以自定义,详细的参考4.2中SDK界面demo:

 

我根据SDK中详细代码, 对在线生成的代码简单增加了一些注释和参数,

以及对返回的数据进行了解析转化,可以参考:

# -*- coding: utf-8 -*-
import json
import base64
import logging

from tencentcloud.common import credential
# 导入可选配置类
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException

# 根据自己使用的模块,导入对应产品模块的client models ++++++++++++++++++++++++++
from tencentcloud.tiia.v20190529 import tiia_client, models


def get_imgtag(img_path):
    try:
        # 实例化一个认证对象,腾讯云账户secretId,secretKey,需注意密钥对的保密+++++++++++++++++++++++++
        cred = credential.Credential(SecretID, SecretKey)

        # 实例化一个http选项,可选的,没有特殊需求可以跳过。
        httpProfile = HttpProfile()
        # 如果需要指定proxy访问接口,可以按照如下方式初始化hp
        # httpProfile = HttpProfile(proxy="http://用户名:密码@代理IP:代理端口")
        # httpProfile.protocol = "https"  # 在外网互通的网络环境下支持http协议(默认是https协议),建议使用https协议
        # httpProfile.keepAlive = True  # 状态保持,默认是False
        # httpProfile.reqMethod = "POST"  # get请求(默认为post请求)
        httpProfile.reqTimeout = 30  # 请求超时时间,单位为秒(默认60秒)+++++++++++++++++++++++++++
        httpProfile.endpoint = "tiia.tencentcloudapi.com"  # 指定接入地域域名(默认就近接入)

        # 实例化一个client选项,可选的,没有特殊需求可以跳过。
        clientProfile = ClientProfile()
        # clientProfile.signMethod = "TC3-HMAC-SHA256"  # 指定签名算法
        # clientProfile.language = "en-US"  # 指定展示英文(默认为中文)
        clientProfile.httpProfile = httpProfile

        # 根据自己需求,实例化要请求产品client对象
        client = tiia_client.TiiaClient(cred, "ap-shanghai", clientProfile)


        # 实例化一个实例信息查询requests请求对象,每个接口都会对应一个request对象。
        req = models.DetectLabelRequest()
        params = {
            "ImageBase64": base64.b64encode(open(img_path, 'rb').read()).rstrip().decode('utf-8'), # 需要这样转码计算++++++++++++++++++
            "Scenes": ["CAMERA"] # 常用:WEB,针对网络图片优化; CAMERA,针对手机摄像头拍摄图片优化,默认WEB,不同模式结果不同,自行选择
        }

        req.from_json_string(json.dumps(params))
        resp = client.DetectLabel(req)
        # 输出json格式的字符串回包:Labels、CameraLabels、AlbumLabels、NewsLabels、RequestId
        # print(resp.to_json_string(indent=2))
        # 也可以取出单个值,如只看Labels
        # print(resp.Labels)
        # return resp.Labels #  "Scenes"为默认的WEB时

        ret_list = []
        # 返回列表项看似是字典,其实是DetectLabelItem类对象,不能序列化,不能用get,反序列化也没用,只能用点语法取值,转化为字典
        for DetectLabelItem in resp.CameraLabels: # "Scenes"为CAMERA时
            DetectLabelItem_to_dict = {}
            # 可信度 1-100
            DetectLabelItem_to_dict['Confidence'] = int(DetectLabelItem.Confidence)
            # Confidence = int(lable.get('Confidence'))
            # 描述
            DetectLabelItem_to_dict['Name'] = DetectLabelItem.Name
            # 一级标签
            DetectLabelItem_to_dict['FirstCategory'] = DetectLabelItem.FirstCategory
            # FirstCategory = lable.get('FirstCategory')
            # 二级标签
            DetectLabelItem_to_dict['SecondCategory'] = DetectLabelItem.SecondCategory
            ret_list.append(DetectLabelItem_to_dict)

        return ret_list
    except TencentCloudSDKException as err:
        print(err)

if __name__ == '__main__':
    SecretID = 'AKxxxoooxxxooo8g17w'
    SecretKey = 'bvxxxoooxxxoooxoxoIM'
    img_path = 'D:\\代码\\xxoo\\wechat_files\\微信图片_20210625142623.jpg'
    get_imgtag(SecretID, SecretKey, img_path)
    

 

4.4 查看调用

可以登录 腾讯云控制台 ,该平台可以看到每一次调用的情况,查看 图像分析 服务的调用情况。

 

posted @ 2021-06-25 17:05  www.pu  Views(953)  Comments(0Edit  收藏  举报