调用阿里云API实现证件照生成

news2025/4/4 14:06:18

目录

  • 1. 作者介绍
  • 2. 算法介绍
    • 2.1 阿里云介绍
    • 2.2 证件照生成背景
    • 2.3 图像分割算法
  • 3.调用阿里云API进行证件照生成实例
    • 3.1 准备工作
    • 3.2 实验代码
    • 3.3 实验结果与分析
  • 参考(可供参考的链接和引用文献)

1. 作者介绍

王逸腾,男,西安工程大学电子信息学院,2022级硕士研究生
研究方向:三维手部姿态和网格估计
电子邮件:2978558373@qq.com

路治东,男,西安工程大学电子信息学院,2022级研究生,张宏伟人工智能课题组
研究方向:机器视觉与人工智能
电子邮件:2063079527@qq.com

2. 算法介绍

2.1 阿里云介绍


阿里云创立于2009年,是全球领先的云计算及人工智能科技公司,致力于以在线公共服务的方式,提供安全、可靠的计算和数据处理能力,让计算和人工智能成为普惠科技。阿里云服务着制造、金融、政务、交通、医疗、电信、能源等众多领域的领军企业,包括中国联通、12306、中石化、中石油、飞利浦、华大基因等大型企业客户,以及微博、知乎、锤子科技等明星互联网公司。在天猫双11全球狂欢节、12306春运购票等极富挑战的应用场景中,阿里云保持着良好的运行纪录
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本
猿辅导、中泰证券、小米、媛福达、Soul和当贝,这些我们耳熟能详的APP或企业中,阿里云给他们提供了性能强大、安全、稳定的云产品与服务。
计算,容器,存储,网络与CDN,安全、中间件、数据库、大数据计算、人工智能与机器学习、媒体服务、企业服务与云通信、物联网、开发工具、迁移与运维管理和专有云等方面,阿里云都做的很不错。

2.2 证件照生成背景

传统做法:通常是人工进行P图,不仅费时费力,而且效果也很难保障,容易有瑕疵。
机器学习做法:通常利用边缘检测算法进行人物轮廓提取。
深度学习做法:通常使用分割算法进行人物分割。例如U-Net网络。
在这里插入图片描述

2.3 图像分割算法

《BiHand: Recovering Hand Mesh with Multi-stage Bisected Hourglass Networks》》里的SeedNet网络是很经典的网络,它把分割任务转变成多个任务。作者的思想是:尽可能的通过多任务学习收拢语义,这样或许会分割的更好或姿态估计的更好。其实这个模型就是多阶段学习网络的一部分,作者想通过中间监督来提高网络的性能。
我提取bihand网络中的SeedNet与训练权重,进行分割结果展示如下
在这里插入图片描述
我是用的模型不是全程的,是第一阶段的。为了可视化出最好的效果,我把第一阶段也就是SeedNet网络的输出分别采用不同的方式可视化。
从左边数第一张图为原图,第二张图为sigmoid后利用plt.imshow(colored_mask, cmap=‘jet’)进行彩色映射。第三张图为网络输出的张量经过sigmoid后,二色分割图,阀闸值0.5。第四张为网络的直接输出,利用直接产生的张量图进行颜色映射。第五张为使用sigmoid处理张量后进行的颜色映射。第六张为使用sigmoid处理张量后进行0,1分割掩码映射。使用原模型和网络需要添加很多代码。下面为修改后的的代码:

下面为修改后的net_seedd代码:# Copyright (c) Lixin YANG. All Rights Reserved.
r"""
Networks for heatmap estimation from RGB images using Hourglass Network
"Stacked Hourglass Networks for Human Pose Estimation", Alejandro Newell, Kaiyu Yang, Jia Deng, ECCV 2016
"""
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from skimage import io,transform,util
from termcolor import colored, cprint

from bihand.models.bases.bottleneck import BottleneckBlock
from bihand.models.bases.hourglass import HourglassBisected
import bihand.utils.func as func
import matplotlib.pyplot as plt

from bihand.utils import misc
import matplotlib.cm as cm
def color_mask(output_ok):
    # 颜色映射
    cmap = plt.cm.get_cmap('jet')

    # 将张量转换为numpy数组
    mask_array = output_ok.detach().numpy()

    # 创建彩色图像
    cmap = cm.get_cmap('jet')
    colored_mask = cmap(mask_array)
    return colored_mask
    # 可视化
    # plt.imshow(colored_mask, cmap='jet')
    # plt.axis('off')
    # plt.show()
def two_color(mask_tensor):
    # 将张量转换为numpy数组
    mask_array = mask_tensor.detach().numpy()

    # 将0到1之间的值转换为二值化掩码
    threshold = 0.5 # 阈值,大于阈值的为白色,小于等于阈值的为黑色
    binary_mask = np.where(mask_array > threshold, 1, 0)
    return binary_mask
    # 可视化
    # plt.imshow(binary_mask, cmap='gray')
    # plt.axis('off')
    # plt.show()
class SeedNet(nn.Module):
    def __init__(
        self,
        nstacks=2,
        nblocks=1,
        njoints=21,
        block=BottleneckBlock,
    ):
        super(SeedNet, self).__init__()
        self.njoints  = njoints
        self.nstacks  = nstacks
        self.in_planes = 64

        self.conv1 = nn.Conv2d(3, self.in_planes, kernel_size=7, stride=2, padding=3, bias=True)
        self.bn1 = nn.BatchNorm2d(self.in_planes)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(2, stride=2)
        self.layer1 = self._make_residual(block, nblocks, self.in_planes, 2*self.in_planes)
        # current self.in_planes is 64 * 2 = 128
        self.layer2 = self._make_residual(block, nblocks, self.in_planes, 2*self.in_planes)
        # current self.in_planes is 128 * 2 = 256
        self.layer3 = self._make_residual(block, nblocks, self.in_planes, self.in_planes)

        ch = self.in_planes # 256

        hg2b, res1, res2, fc1, _fc1, fc2, _fc2= [],[],[],[],[],[],[]
        hm, _hm, mask, _mask = [], [], [], []
        for i in range(nstacks): # 2
            hg2b.append(HourglassBisected(block, nblocks, ch, depth=4))
            res1.append(self._make_residual(block, nblocks, ch, ch))
            res2.append(self._make_residual(block, nblocks, ch, ch))
            fc1.append(self._make_fc(ch, ch))
            fc2.append(self._make_fc(ch, ch))
            hm.append(nn.Conv2d(ch, njoints, kernel_size=1, bias=True))
            mask.append(nn.Conv2d(ch, 1, kernel_size=1, bias=True))

            if i < nstacks-1:
                _fc1.append(nn.Conv2d(ch, ch, kernel_size=1, bias=False))
                _fc2.append(nn.Conv2d(ch, ch, kernel_size=1, bias=False))
                _hm.append(nn.Conv2d(njoints, ch, kernel_size=1, bias=False))
                _mask.append(nn.Conv2d(1, ch, kernel_size=1, bias=False))

        self.hg2b  = nn.ModuleList(hg2b) # hgs: hourglass stack
        self.res1  = nn.ModuleList(res1)
        self.fc1   = nn.ModuleList(fc1)
        self._fc1  = nn.ModuleList(_fc1)
        self.res2  = nn.ModuleList(res2)
        self.fc2   = nn.ModuleList(fc2)
        self._fc2  = nn.ModuleList(_fc2)
        self.hm   = nn.ModuleList(hm)
        self._hm  = nn.ModuleList(_hm)
        self.mask  = nn.ModuleList(mask)
        self._mask = nn.ModuleList(_mask)


    def _make_fc(self, in_planes, out_planes):
        bn = nn.BatchNorm2d(in_planes)
        conv = nn.Conv2d(in_planes, out_planes, kernel_size=1, bias=False)
        return nn.Sequential(conv, bn, self.relu)


    def _make_residual(self, block, nblocks, in_planes, out_planes):
        layers = []
        layers.append( block( in_planes, out_planes) )
        self.in_planes = out_planes
        for i in range(1, nblocks):
            layers.append(block( self.in_planes, out_planes))
        return nn.Sequential(*layers)

    def forward(self, x):

        l_hm, l_mask, l_enc = [], [], []
        x = self.conv1(x) # x: (N,64,128,128)
        x = self.bn1(x)
        x = self.relu(x)

        x = self.layer1(x)
        x = self.maxpool(x) # x: (N,128,64,64)
        x = self.layer2(x)
        x = self.layer3(x)

        for i in range(self.nstacks): #2
            y_1, y_2, _ = self.hg2b[i](x)

            y_1 = self.res1[i](y_1)
            y_1 = self.fc1[i](y_1)
            est_hm = self.hm[i](y_1)
            l_hm.append(est_hm)

            y_2 = self.res2[i](y_2)
            y_2 = self.fc2[i](y_2)
            est_mask = self.mask[i](y_2)
            l_mask.append(est_mask)

            if i < self.nstacks-1:
                _fc1 = self._fc1[i](y_1)
                _hm = self._hm[i](est_hm)
                _fc2 = self._fc2[i](y_2)
                _mask = self._mask[i](est_mask)
                x = x + _fc1 + _fc2 + _hm + _mask
                l_enc.append(x)
            else:
                l_enc.append(x + y_1 + y_2)
        assert len(l_hm) == self.nstacks
        return l_hm, l_mask, l_enc

if __name__ == '__main__':
    #a = torch.randn(10, 3, 256, 256)
    # SeedNetmodel = SeedNet()
    # output1,output2,output3 = SeedNetmodel(a)
    # print(output1,output2,output3)

    #total_params = sum(p.numel() for p in SeedNetmodel.parameters())/1000000
    #print("Total parameters: ", total_params)
    pretrained_weights_path = 'E:/bihand/released_checkpoints/ckp_seednet_all.pth.tar'
    img_rgb_path=r"E:\FreiHAND\training\rgb\00000153.jpg"
    img=io.imread(img_rgb_path)
    resized_img = transform.resize(img, (256, 256), anti_aliasing=True)
    img256=util.img_as_ubyte(resized_img)


    #plt.imshow(resized_img)
    #plt.axis('off')  # 关闭坐标轴
    #plt.show()


    ''' implicit HWC -> CHW, 255 -> 1 '''
    img1 = func.to_tensor(img256).float() #转换为张量并且进行标准化处理
    ''' 0-mean, 1 std,  [0,1] -> [-0.5, 0.5] '''
    img2 = func.normalize(img1, [0.5, 0.5, 0.5], [1, 1, 1])
    img3 = torch.unsqueeze(img2, 0)
    ok=img3
    print(img.shape)
    SeedNetmodel = SeedNet()

    misc.load_checkpoint(SeedNetmodel, pretrained_weights_path)#加载权重

    output1, output2, output3 = SeedNetmodel(img3)
    #mask_tensor = torch.rand(1, 64, 64)
    output=output2[1] # 1,1,64,64
    output_1=output[0]# 1,64,64
    output_ok=torch.sigmoid(output_1[0])
    output_real=output_1[0].detach().numpy()#直接产生的张量图
    color_mask=color_mask(output_ok) #显示彩色分割图
    two_color=two_color(output_ok)#显示黑白分割图


    see=output_ok.detach().numpy() 


    # 使用Matplotlib库显示分割掩码
    # plt.imshow(see, cmap='gray')
    # plt.axis('off')
    # plt.show()
   # print(output1, output2, output3)


    images = [resized_img, color_mask, two_color,output_real,see,see]
    rows = 1
    cols = 4

    # 创建子图并展示图像
    fig, axes = plt.subplots(1, 6, figsize=(30, 5))

    # 遍历图像列表,并在每个子图中显示图像
    for i, image in enumerate(images):
        ax = axes[i] if cols > 1 else axes  # 如果只有一列,则直接使用axes
        if i ==5:
            ax.imshow(image, cmap='gray')
        else:
         ax.imshow(image)

        ax.imshow
        ax.axis('off')

    # 调整子图之间的间距
    plt.subplots_adjust(wspace=0.1, hspace=0.1)

    # 展示图像
    plt.show()

上述的代码文件是在bihand/models/net_seed.py中,全部代码链接在https://github.com/lixiny/bihand。
把bihand/models/net_seed.p中的代码修改为我提供的代码即可使用作者训练好的模型和进行各种可视化。(预训练模型根据作者代码提示下载)

3.调用阿里云API进行证件照生成实例

3.1 准备工作

1.找到接口
在这里插入图片描述
进入下面链接即可快速访问
link
2.购买试用包
在这里插入图片描述
3.参看APPcode
在这里插入图片描述
4.下载代码
在这里插入图片描述
5.参数说明
在这里插入图片描述

3.2 实验代码

# !/usr/bin/python
# encoding: utf-8
"""
===========================证件照制作接口===========================
"""

import requests
import json
import base64
import hashlib


class Idphoto:
    def __init__(self, appcode, timeout=7):
        self.appcode = appcode
        self.timeout = timeout

        self.make_idphoto_url = 'https://idp2.market.alicloudapi.com/idphoto/make'

        self.headers = {
            'Authorization': 'APPCODE ' + appcode,
        }

    def get_md5_data(self, body):
        """
        md5加密
        :param body_json:
        :return:
        """

        md5lib = hashlib.md5()
        md5lib.update(body.encode("utf-8"))
        body_md5 = md5lib.digest()
        body_md5 = base64.b64encode(body_md5)
        return body_md5

    def get_photo_base64(self, file_path):
        with open(file_path, 'rb') as fp:
            photo_base64 = base64.b64encode(fp.read())

        photo_base64 = photo_base64.decode('utf8')
        return photo_base64

    def aiseg_request(self, url, data, headers):
        resp = requests.post(url=url, data=data, headers=headers, timeout=self.timeout)
        res = {"status_code": resp.status_code}
        try:
            res["data"] = json.loads(resp.text)
            return res
        except Exception as e:
            print(e)

    def make_idphoto(self, file_path, bk, spec="2"):
        """
        证件照制作接口
        :param file_path:
        :param bk:
        :param spec:
        :return:
        """
        photo_base64 = self.get_photo_base64(file_path)

        body_json = {
            "photo": photo_base64,
            "bk": bk,
            "with_photo_key": 1,
            "spec": spec,
            "type": "jpg"
        }

        body = json.dumps(body_json)
        body_md5 = self.get_md5_data(body=body)
        self.headers.update({'Content-MD5': body_md5})

        data = self.aiseg_request(url=self.make_idphoto_url, data=body, headers=self.headers)
        return data


if __name__ == "__main__":
    file_path = "图片地址"

    idphoto = Idphoto(appcode="你的appcode")

    d = idphoto.make_idphoto(file_path, "red", "2")
    print(d)

3.3 实验结果与分析

在这里插入图片描述
原图片
在这里插入图片描述
背景为红色生成的证件照
在这里插入图片描述
背景为蓝色生成的证件照
在这里插入图片描述
另外尝试了使用柴犬照片做实验,也生成了证件照
原图
在这里插入图片描述
背景为红色生成的证件照
在这里插入图片描述

参考(可供参考的链接和引用文献)

1.参考:BiHand: Recovering Hand Mesh with Multi-stage Bisected Hourglass Networks(BMVC2020)
论文链接:https://arxiv.org/pdf/2008.05079.pdf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/627950.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ASEMI代理英飞凌TLD5097EL:理解和使用LED驱动器的综合指南

编辑-Z TLD5097EL是一款创新的LED驱动器&#xff0c;在照明行业掀起了波澜。这项先进的技术提供了广泛的好处&#xff0c;包括提高能源效率、延长使用寿命和增强性能。在本综合指南中&#xff0c;我们将探讨TLD5097EL的功能和优点&#xff0c;并提供如何有效利用该LED驱动器优…

python -- 绘制colorbar时设置标签为居中显示

python – 绘制colorbar时设置标签为居中显示 在海洋气象领域的相关研究中&#xff0c;对于一些异常信号的二维填色图绘制时&#xff0c;通常在设置colorbar都是以0为中心对称分布的。而在绘制colorbar时&#xff0c;由于存在负号会使得默认colorbar标签不太好看&#xff08;强…

window服务器环境将springboot jar包安装成一个window服务自启动

目录 1.下载WinSW工具 下载winswhttps://github.com/winsw/winsw/releases 2.新建一个Window Service信息的xml文件 3.将xml和exe重命名 4.安装卸载服务 5.修改配置文件 6.常用命令(注意winsw是exe名字 1.下载WinSW工具 下载winswhttps://github.com/winsw/winsw/rele…

图像降噪网络:KBNet 论文笔记

0 前言 Zhang Y, Li D, Shi X, et al. KBNet: Kernel Basis Network for Image Restoration[J]. arXiv preprint arXiv:2303.02881, 2023. https://arxiv.org/abs/2303.02881 论文主要提出了 Kernel Basis Attention Module 注意力模块&#xff0c;称为 KBA 模块。该模块可以轻…

[中阳期货】端午都有哪些习俗,为什么不能说快乐?

端午节&#xff08;屈原故里端午习俗&#xff09;&#xff0c;流行于湖北省宜昌市、秭归县的传统民俗&#xff0c;国家级非物质文化遗产之一。 “五月五&#xff08;农历&#xff09;&#xff0c;过端午。”端午节是中华民族的传统节日。《续齐谐记》、《荆楚岁时记》载&#x…

AI 人工智能介绍(一)

人工智能&#xff08;AI&#xff09;是一种利用计算机程序和算法来模拟人类智能的技术。通俗地说&#xff0c;就是让计算机能够像人一样思考、学习、推理和决策。 人工智能改变了我们的生活&#xff01;它被广泛应用于语音识别、计算机视觉、自然语言处理、智能机器人等多种领…

ubuntu20.04虚拟机安装

下载对应版本镜像文件&#xff08;iso&#xff09; 下载链接&#xff1a;https://releases.ubuntu.com/jammy/ 虚拟机安装工具为VMware 这里我的版本为下图所示 使用vmware创建虚拟机 1&#xff0c;点击 “创建新的虚拟机” 2&#xff0c;进入向导&#xff0c;选择自定义 …

基于docker部署的Selenium Grid分布式自动化测试

01、什么是Selenium Grid Selenium Grid是Selenium套件的一部分&#xff0c;它专门用于并行运行多个测试用例在不同的浏览器、操作系统和机器上。 Selenium Grid有两个版本——老版本Grid 1和新版本Grid 2。我们只对新版本做介绍&#xff0c;因为Selenium团队已经逐渐遗弃老版…

非线性规划求解方法:序列线性规划(Sequential linear programming)

来源&#xff1a;Cornell University Computational Optimization Open Textbook&#xff1a;SLP​​​​​​​ 目录 1.介绍 2.理论和方法 2.1 问题形式 2.1.1 NLP问题形式 2.1.2 SLP问题形式 2.2 步长边界 Step Bounds 2.3 完整的SLP算法 3.案例 3.1 example1 3.2…

数据结构:树状数组详解

一. 背景 那么我们为什么要用树状数组呢? 在解决一些区间求和的问题中 , 简单描述就是&#xff0c;对于一个给定的数组A&#xff0c;希望能够设计一个update函数来修改其中一个数的值&#xff0c;然后再设计一个sum函数来计算数组下标再给定参数l和r之间的值之和。关键点在于…

Docker Swarm 集群搭建和使用 —— 筑梦之路

简单介绍 swarm 集群由管理节点&#xff08;Manager&#xff09;和工作节点&#xff08;Worker&#xff09;构成。 管理节点&#xff1a;主要负责整个集群的管理工作包括集群配置、服务管理等所有跟集群有关的工作。诸如监控集群状态、分发任务至工作节点等操作。 工作节点&…

【计算机视觉】使用 notebook 展示如何下载和运行 CLIP models,计算图片和文本相似度,实现 zero-shot 图片分类

文章目录 一、CLIP 模型二、准备三、加载模型四、查看图片处理器五、文本分词六、输入图片和文本&#xff0c;并可视化七、将图片和文字 encode 生成特征八、计算 cosine 相似度九、零样本进行图片分类十、编写函数进行图片分类十一、测试自己的函数十二、编写函数对多图片进行…

面对职业发展“迷茫期”除了抱怨焦虑我们还能做什么?

关注“软件测试藏经阁”微信公众号&#xff0c;回复暗号【软件测试】&#xff0c;即可获取氪肝整理的全套测试资源 Java和Python做自动化测试&#xff0c;哪个更有优势&#xff1f;这两个语言都是很流行的语言&#xff0c;所以从技术上很难说谁好谁不好的。因为要说好不好得看…

linux安装homeassistant(智能设备远程控制开源框架)

1、安装docker 先切换到root 用户&#xff0c;先安装一些基本环境&#xff1a; yum install -y yum-utils device-mapper-persistent-data lvm2添加阿里云软件源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo然后安装 D…

QT+OpenGL高级光照 Blinn-Phong和Gamma校正

QTOpenGL高级光照1 本篇完整工程见gitee:QtOpenGL 对应点的tag&#xff0c;由turbolove提供技术支持&#xff0c;您可以关注博主或者私信博主 Blinn-Phong 冯氏光照&#xff1a;视线与反射方向之间的夹角不小于90度&#xff0c;镜面光分量会变成0.0&#xff08;不是很合理&am…

死信队列小结

死信队列是RabbitMQ中非常重要的一个特性。简单理解&#xff0c;他是RabbitMQ对于未能正常消费的消息进行的 一种补救机制。死信队列也是一个普通的队列&#xff0c;同样可以在队列上声明消费者&#xff0c;继续对消息进行消费处理。 对于死信队列&#xff0c;在RabbitMQ中主要…

Spring 是什么?IoC 和 DI的区别

1. Spring 是什么?2. IoC是什么&#xff1f; 2.DI概念说明 1. Spring 是什么? 我们通常讲的Spring指的是Spring Framework(Spring框架),它是一个开源的框架,有着活跃而庞大的社区,这也是它之所谓经久不衰的原因。官方的解读是:Spring官网 翻译过来就是:Spring使Java编程对每…

学会这5个步骤,就能轻轻松松地获取代码覆盖率报告

目录 前言&#xff1a; 1、创建main函数的test文件 2、插桩方式编译源码 3、运行主服务 4、执行测试用例 5、优雅退出主服务&#xff0c;并生成覆盖率报告 前言&#xff1a; 代码覆盖率报告可以帮助我们了解测试用例的质量和覆盖程度。 小编前期所测项目多为go语言研发&…

《C++高级编程》读书笔记(一:C++和标准库速成)

1、参考引用 C高级编程&#xff08;第4版&#xff0c;C17标准&#xff09;马克葛瑞格尔 2、建议先看《21天学通C》 这本书入门&#xff0c;笔记链接如下 21天学通C读书笔记&#xff08;文章链接汇总&#xff09; 1. C 基础知识 1.1 小程序 “hello world” // helloworld.cpp…

开源项目合集......

likeshop开源商城系统&#xff0c;公众号商城、H5商城、微信小程序商城、抖音小程序商城、字节小程序商城、头条小程序商城、安卓App商城、苹果App商城代码全开源&#xff0c;免费商用。 适用场景&#xff1a;B2C商城、新零售商城、社交电商商城、分销系统商城、小程序商城、商…