首页 > 编程语言 >基于华为云FunctionGraph和ModelArts的智能动漫头像生成:从自拍到AI风格化的编程

基于华为云FunctionGraph和ModelArts的智能动漫头像生成:从自拍到AI风格化的编程

时间:2024-11-13 22:50:55浏览次数:3  
标签:const 函数 ModelArts image AI file 风格化 FunctionGraph color

文章目录

1 引言

在当今人工智能快速发展的时代,图像处理和风格化技术正在广泛应用于各类场景,从个人头像美化到社交媒体内容创作,AI技术赋予了图像全新的表达方式。基于此,华为云推出了FunctionGraph与ModelArts相结合的智能动漫化头像处理方案。FunctionGraph作为无服务器计算服务,提供了灵活的编程环境,而ModelArts则为AI模型的训练、部署和管理提供了强大支持。通过将这两者结合,开发者无需关注底层资源配置,仅需编写简单的代码即可实现头像的动漫化风格转换。这项技术不仅操作简便,还具有广泛的应用前景,为内容创作者、社交媒体用户和开发者提供了高效的AI解决方案。

2 背景介绍

2.1 华为云FunctionGraph与ModelArts简介

在这里插入图片描述

大体实验步骤说明:

① 安装FunctionGraph插件;

② 创建函数;

③ 部署函数;

④ 函数配置委托;

⑤ 函数配置触发器;

⑥ 函数添加依赖包;

⑦ 订阅模型并部署;

⑧ 制作动漫头像。

3 项目准备

3.1 注册与登录华为云账号

进入开发者空间,领取云主机
在这里插入图片描述

4 实验步骤

4.1 首先我们配置云主机

在这里插入图片描述

进入云桌面
在这里插入图片描述

4.2 安装FunctionGraph插件

这里我们可以选择两种安装方式!

方式一:在线安装

进入云主机 ,打开CodeArts IDE,点击左侧“扩展”搜索“CodeArts FunctionGraph”点击安装该插件。

方式二:本地安装

前往鲲鹏社区官网下载插件CodeArts FunctionGraph到云主机,下载地址为:CodeArts IDE 插件市场 。

这里我们采用方式一!
在这里插入图片描述

4.3 创建函数

接下来按照步骤即可
在这里插入图片描述

选择Http Function函数。

选择Hello World

打开工程目录,创建新文件夹:templates

在templates中创建文件index.html
在这里插入图片描述

html代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FunctionGraph 动漫头像制作</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background: repeating-linear-gradient(45deg, #ddd 0 2px, transparent 2px 4px), repeating-linear-gradient(-45deg, #ddd 0 2px, transparent 2px 4px);
            text-align: center;
        }

        h1 {
            color: #333;
        }

        p.description {
            color: #666;
        }

        #upload-button {
            padding: 15px 30px;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 20px;
            margin-top: 20px;
        }
        .image-container {
            display: flex;
            margin-top: 50px;
            justify-content: center;
            align-items: center;
        }

        .image-box {
            margin: 0 40px;
            padding: 0;
            width: 500px;
            height: 500px;
            display: flex;
            flex-direction: row;
            position: relative;
            letter-spacing: .3px;
            padding: 10px;
            border-radius: 10px;
            transition: background-color .3s ease-in-out;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: white;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
        }

        #original-image-box, #preview-container {
            border: 2px dashed #6dcff6;
            border-radius: 10px;
            width: 480px;
            height: 480px;
        }

        .but-box {
            margin: 0px 30px;
            padding: 0;
            width: 500px;
            display: flex;
            justify-content: center;
            font-size: 30px;
            font-weight: 700;
        }

        .image-box img {
            height: 100%;
            max-width: 100%;
        }

        .error-message {
            color: red;
            margin-top: 10px;
        }

        .size-warning {
            font-size: 20px;
            color: orange;
            margin-top: 10px;
        }

        button {
            padding: 20px 40px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 20px;
        }

        h1 {
            font-size: 40px;
        }

        .triangle-arrow {
            width: 0;
            height: 0;
            border-top: 20px solid transparent;
            border-bottom: 20px solid transparent;
            border-left: 30px solid blue;
        }

        .loading-mask {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.1);
            display: none;
            justify-content: center;
            align-items: flex-end;
            z-index: 999;
        }

        .loading-text {

            font-size: 30px;
            color: red;
        }
    </style>
</head>

<body>

<h1>动漫风格头像制作案例:用户上传自拍照片,调用华为云上算力,一键生成动漫风格人物头像。</h1>
<input type="file" id="image-input" style="display: none;">
<button id="upload-button">请上传照片</button>
<p class="size-warning">上传小于 6MB 的图片。</p>
<p class="error-message" id="size-error"></p>

<div class="image-container">
    <div class="image-box">
        <div id="original-image-box">

        </div>
    </div>
    <div class="triangle-arrow"></div>
    <div class="image-box">
        <div id="preview-container">

        </div>
    </div>
</div>

<div class="image-container">
    <div class="but-box">
        原图
    </div>
    <div class="but-box">
        效果图
    </div>
</div>
<div class="loading-mask" id="loading-mask">
    <p class="loading-text">照片生成中...</p>
</div>
<script>
    const uploadButton = document.getElementById('upload-button');
    const imageInput = document.getElementById('image-input');
    const originalImageBox = document.getElementById('original-image-box');
    const imagePreview = document.getElementById("preview-container");
    const sizeError = document.getElementById('size-error');
    const sizeWarning = document.querySelector('.size-warning');
    const loadingMask = document.getElementById('loading-mask');
    uploadButton.addEventListener('click', () => {
        imageInput.click();
    });
    imageInput.addEventListener('change', () => {
        const file = imageInput.files[0];
        if (file) {
            if (file.size > 6 * 1024 * 1024) {
                sizeError.textContent = '图片大小不能超过 6MB。';
                sizeWarning.textContent = '';
                return;
            }

            const img = document.createElement('img');
            img.src = URL.createObjectURL(file);
            originalImageBox.innerHTML = '';
            originalImageBox.appendChild(img);
            if (!file) {
                console.log("!file ")
                return;
            }
            const formData = new FormData();
            formData.append("image", file);
            loadingMask.style.display = 'flex';
            fetch("/carton/upload", {
                method: "POST",
                body: formData,
            })
                .then((response) => response.text())
                .then((data) => {
					let parsedObject;
                    try {
                        parsedObject = JSON.parse(data);
                    } catch (error) {
                        console.error('JSON 解析错误:', error);
                        parsedObject = null; // 或者其他默认值,根据你的需求设置
                    }

                    const animeImgElement = document.createElement('img');
                    animeImgElement.src = "data:image/png;base64," +
                        parsedObject.results[0];
                    imagePreview.innerHTML = '';
                    imagePreview.appendChild(animeImgElement);
                    loadingMask.style.display = 'none';
                })
                .catch((error) => {
                    loadingMask.style.display = 'none';
                    console.error(error);
                    alert("处理失败");
                });
        }
    });

</script>

</body>
</html>

删除index.js,创建新文件app.py

修改app.py内容如下

from flask import Flask, request, render_template
import requests
import os

MODEL_ART_API = os.getenv('MODEL_ART_API')

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/carton/upload', methods=['POST'])
def upload_file():
    if 'image' not in request.files:
        return 'No file uploaded.', 400
    
    file = request.files['image']
    if file.filename == '':
        return 'Filename is empty.', 400
    
    resp = model_art_pic_carton(file)

    print(resp)
    return resp.json()

def model_art_pic_carton(file):
    payload = {}
    files=[  ('images',(file.filename,file,'image/png'))]
    headers = {
    'x-auth-token': get_token_from_fg_header()
    }
    response = requests.request("POST", MODEL_ART_API, headers=headers, data=payload, files=files,verify=False)
    return response

# 从FunctionGraph平台发送的请求里获取鉴权token 
# 需要先配置委托 并且 在高级设置打开传入秘钥开关
def get_token_from_fg_header():
    return request.headers.get("X-Cff-Auth-Token")

if __name__ == '__main__':
    app.run(debug=True,port=8000,host="0.0.0.0")


# 从FunctionGraph平台发送的请求里获取鉴权token 
# 需要先配置委托 并且 在高级设置打开传入秘钥开关
def get_token_from_fg_header():
    return request.headers.get("X-Cff-Auth-Token")

if __name__ == '__main__':
    app.run(debug=True,port=8000,host="0.0.0.0")

修改bootstrap文件内容如下:

/opt/function/runtime/python3.6/rtsp/python/bin/python3 $RUNTIME_CODE_ROOT/app.py

4.4 部署函数

回到插件页面,选择部署函数
在这里插入图片描述

选择新建的函数下的yml文件

部署环境选择“华北-北京四

之后就部署成果了,点击“选择要展示的Region”,选择“华北-北京四”,可以看到该区域下刚部署好的函数:carton-generation,右键选择函数,点击浏览器打开,跳转到函数详情界面
在这里插入图片描述

4.5 函数配置委托

这里我简单的贴图,具体流程请查看官方文档
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.6 函数配置触发器

点击“创建触发器”,选择“触发器类型”,选择“分组”(如果没有分组需先创建),选择“安全认证”,设置“后端超时”。
在这里插入图片描述

4.7 函数添加依赖包

返回“函数工作流”管理界面,选择“依赖包管理”,点击“创建依赖包”。
这里有些同学可能找不到,我们从上面搜索即可
在这里插入图片描述

填写“依赖包名称”,代码包上传方式为“从OBS上传文件”,将OBS链接粘贴到“OBS链接URL”中(OBS URL:https://functionstorage-cn-north-4.obs.cn-north-4.myhuaweicloud.com/applications/depdency/flask-2_0_1-1.zip )

运行时语言为“Python3.9”。
在这里插入图片描述

进入函数详情页底部,点击“添加依赖包”。这里有些人可能也找不到,下图可以帮你更快找到

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.8 订阅模型并部署AI应用

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

编辑环境变量
在这里插入图片描述

4.9 制作动漫头像

访问URL
在这里插入图片描述

网上下载一个美女图片
在这里插入图片描述

体验完别忘了关机哦

在这里插入图片描述

5 总结与心得

本文粗略的介绍了如何利用华为云的FunctionGraph和ModelArts服务,实现智能化的动漫头像生成。通过FunctionGraph的无服务器计算特性,开发者无需管理底层计算资源,只需关注代码逻辑,而ModelArts则提供了强大的AI模型支持,使得图像风格化处理变得简单高效。文章详细讲解了上传头像、调用ModelArts模型进行动漫化处理的具体步骤,并展示了处理后的效果。这样的AI风格化技术不仅可以应用于个人头像,还具有广泛的商业应用前景,如内容创作、社交媒体和游戏等多个领域。这一解决方案展示了华为云AI生态系统的便捷和强大,同时也让开发者认识到云端AI服务的高效性和灵活性,是推动AI技术应用落地的良好范例。

我正在参加【有奖征文 第34期】华为开发者空间一行代码快速上云,更有开发者周边等你拿!
链接:https://bbs.huaweicloud.com/blogs/438987

标签:const,函数,ModelArts,image,AI,file,风格化,FunctionGraph,color
From: https://blog.csdn.net/null18/article/details/143715638

相关文章

  • 【AI换脸整合包及教程】Rope:AI 换脸工具的功能、原理、应用
    在人工智能技术迅猛发展的当下,AI换脸技术无疑是近年来备受瞩目的焦点之一。其中,Rope作为一款开源的AI换脸工具,因其出色的易用性和强大的功能而广受青睐。本文将对Rope的功能、技术原理、应用场景以及所面临的法律和伦理问题进行详细阐述。一、Rope的主要功能Rope是......
  • aider: 一个 terminal 中的开源 AI 编程助手 & benchmark
    1.AIpairprogramminginterminalaiderGitHub可自由配置任意的LLM接口功能:接收需求:Addnewfeaturesortestcases.Describeabug.PasteinanerrormessageororGitHubissueURL.Refactorcode.Updatedocs.修改代码文件自动执行gitcommits并携带......
  • 操作系统复习2-wait、signal操作第二部分
    4.佩奇、米老鼠、汤姆一起玩放水果的游戏。佩奇不停的往空盘子中放苹果米老鼠不停的取苹果,汤姆不停的取橘子。假设这个盘子最多能放的水果且他们三个不能同时取用。完成如下两问请写出记录型信号量的wait和signal操作的定义(7分)。请用信号量机制和wait和signal操作实现这三......
  • The sol to pairing
    Thesoltopairinghttps://www.luogu.com.cn/problem/P11187思路把答案序列中相邻而相等的两个数,我们称之为“块”。那么可以发现,对于以某块为结尾的一个答案序列,其一定是由一个结尾不为该块的序列转移而来。因而,本题具有最优子结构性质,可以使用动态规划求解。\(1.\)对于......
  • NIZK零知识证明-Groth10-Short Pairing-based Non-interactive Zero-Knowledge Argume
    点个关注吧谢谢!有需要论文知道、审稿,申博资料准备,答辩等的可以私信前序文章见:一;二。五、CommonReferenceString公共字符串设定q=n......
  • 比ChatGPT更酷的AI工具
    相较于寻找比ChatGPT更酷的AI工具,这听起来似乎是个挑战,因为ChatGPT已经以它强大的综合性能在AI界大名鼎鼎。然而,每个工具都有其独特的优势,特别是在特定的应用场景下,其他AI工具可能会展现出与ChatGPT不同的魅力。接下来,我将向大家介绍三款我认为字在各自领域非常酷的AI工具。......
  • Single-Agent vs Multi-Agent AI Comparison
    Single-AgentvsMulti-AgentAIComparisonhttps://integrail.ai/blog/single-agent-vs-multi-agent-ai-comparison ChoosingtheRightSystemThechoicebetweensingle-agentandmulti-agentsystemsdependsonthespecificrequirementsofyourproject:ForS......
  • 2024 人工智能全景报告《State of AI Report 2024》出炉!
    文章目录Part1:研究进展1.1模型性能提升与竞争1.2模型技术创新Part2:行业趋势2.1硬件竞争格局2.2商业模式转变Part3:现有政策3.1各国监管举措3.2数据隐私与安全Part4:安全问题4.1安全意识转变4.2安全风险应对Part5:未来预测5.12025十大预测5.22023年度报......
  • 阿里云通义大模型团队开源Qwen2.5-Coder:AI编程新纪元
    ......
  • 百度发布 AI 眼镜:全球首搭中文大模型,支持边走边问;OpenAI 联合创始人宣布回归,主抓重大
       开发者朋友们大家好: 这里是「RTE开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享RTE(Real-TimeEngagement)领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表编......