zoukankan      html  css  js  c++  java
  • Python 调用图像融合API

    Python 调用图像融合API

    本文记录使用Python,调用腾讯AI开放平台的图像融合API。官网给出的Demo用的是PHP,博主作为Python的粉丝,自然想用它来和『最好的』的语言一较高下,顺便加深对服务调用的理解

    官网PHP实现

    腾讯的官方文档应该写的非常详细了,可以直接运行的PHP代码如下:

    <?php
    
    // getReqSign :根据 接口请求参数 和 应用密钥 计算 请求签名
    // 参数说明
    //   - $params:接口请求参数(特别注意:不同的接口,参数对一般不一样,请以具体接口要求为准)
    //   - $appkey:应用密钥
    // 返回数据
    //   - 签名结果
    function getReqSign($params /* 关联数组 */, $appkey /* 字符串*/)
    {
        // 1. 字典升序排序
        ksort($params);
    
        // 2. 拼按URL键值对
        $str = '';
        foreach ($params as $key => $value)
        {
            if ($value !== '')
            {
                $str .= $key . '=' . urlencode($value) . '&';
            }
        }
    
        // 3. 拼接app_key
        $str .= 'app_key=' . $appkey;
    
        // 4. MD5运算+转换大写,得到请求签名
        $sign = strtoupper(md5($str));
        return $sign;
    }
    
    
    // doHttpPost :执行POST请求,并取回响应结果
    // 参数说明
    //   - $url   :接口请求地址
    //   - $params:完整接口请求参数(特别注意:不同的接口,参数对一般不一样,请以具体接口要求为准)
    // 返回数据
    //   - 返回false表示失败,否则表示API成功返回的HTTP BODY部分
    function doHttpPost($url, $params)
    {
        $curl = curl_init();
    
        $response = false;
        do
        {
            // 1. 设置HTTP URL (API地址)
            curl_setopt($curl, CURLOPT_URL, $url);
    
            // 2. 设置HTTP HEADER (表单POST)
            $head = array(
                'Content-Type: application/x-www-form-urlencoded'
            );
            curl_setopt($curl, CURLOPT_HTTPHEADER, $head);
    
            // 3. 设置HTTP BODY (URL键值对)
            $body = http_build_query($params);
            curl_setopt($curl, CURLOPT_POST, true);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
    
            // 4. 调用API,获取响应结果
            curl_setopt($curl, CURLOPT_HEADER, false);
            curl_setopt($curl, CURLOPT_NOBODY, false);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            $response = curl_exec($curl);
            if ($response === false)
            {
                $response = false;
                break;
            }
    
            $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
            if ($code != 200)
            {
                $response = false;
                break;
            }
        } while (0);
    
        curl_close($curl);
        return $response;
    }
    
    
    
    // 图片base64编码
    $path   = 'test.jpg';
    $data   = file_get_contents($path);
    $base64 = base64_encode($data);
    
    // 设置请求数据
    $appkey = 'your_appkey';
    $params = array(
        'app_id'     => 'your_app_id',
        'image'      => $base64,
        'model'      => '1',
        'time_stamp' => strval(time()),
        'nonce_str'  => strval(rand()),
        'sign'       => '',
    );
    $params['sign'] = getReqSign($params, $appkey);
    
    // 执行API调用
    $url = 'https://api.ai.qq.com/fcgi-bin/ptu/ptu_facemerge';
    $response = doHttpPost($url, $params);
    echo $response;
    

    根据此程序,可以返回融合图片的base64编码,再解码就可以得到图片

    Python版实现

    以下代码是博主参照php的改写而成,值得注意的问题是urlencode是一种特定的数据格式,尤其是图片信息一定要按此编码,否则返回错误信息

    # coding=utf-8
    import requests
    import time
    import random
    import hashlib
    import base64
    from urllib import urlencode
    
    
    def get_sign(para, app_key):
        # 签名的key有严格要求,按照key升序排列
        data = sorted(para.items(), key=lambda item: item[0])
        s = urlencode(data)
        # app_key最后加
        s += '&app_key=' + app_key
        # 计算md5报文信息
        md5 = hashlib.md5()
        md5.update(s)
        digest = md5.hexdigest()
        return digest.upper()
    
    
    url = 'https://api.ai.qq.com/fcgi-bin/ptu/ptu_facemerge'
    app_key = 'your_app_key'
    # 读取图片数据
    raw_data = open('test.jpg').read()
    image_data = base64.b64encode(raw_data)
    
    # 定义发送的post数据
    data = {
        'app_id': 'your_app_id',
        'image': image_data,
        'model': '1',  # 选定想要融合的模板
        'time_stamp': str(int(time.time())),
        'nonce_str': str(random.random()),
    }
    
    data['sign'] = get_sign(data, app_key)
    
    # 发送post请求
    r = requests.post(url, data=data)
    # 将得到的数据解码,然后保存到jpg
    res_image = base64.b64decode(r.json()['data']['image'])
    img = open('out.jpg', 'w')
    img.write(res_image)
    img.close()
    

    效果

    输入图片(网上的人脸图片,侵删)

    test.jpg

    腾讯给出的融合模板1

    输出

    out.jpg

    小结

    这次实验的逻辑其实不是很复杂,知识点主要是签名算法POST请求。可以看到Python的代码比PHP简短得多,主要是用到了一些封装好的库

    有了人脸融合这项服务后,感觉可以做很多有趣的事情~

  • 相关阅读:
    java开发编码规范
    Spring Boot 配置文件密码加密两种方案
    qmake生成VS的vcproj/sln工程文件
    R语言爬取动态网页之环境准备
    R实现pm2.5地图数据展示
    【Yii系列】最佳实践之后台业务框架
    【Yii系列】Yii2.0基础框架
    【Python系列】Python自动发邮件脚本-html邮件内容
    【PHP系列】PHP组件详解
    【Yii系列】错误处理和日志系统
  • 原文地址:https://www.cnblogs.com/fanghao/p/8988507.html
Copyright © 2011-2022 走看看