产品应用实践:智能头像动漫化处理案例介绍【华为开发者空间】
概述
本实验聚焦于利用华为云的FunctionGraph和ModelArts平台,构建一个智能头像动漫化处理应用。该应用允许用户上传自己的头像图片,并通过调用部署在ModelArts上的深度学习模型,将这些图片转换为具有独特风格的动漫头像。本文不仅会详细介绍技术架构与实现步骤,还将深入探讨部署流程,确保读者能够全面理解并实际操作。
【流程说明】:根据官方文档介绍,本实验的步骤主要分成以下八个:
① 安装FunctionGraph插件;
② 创建函数;
③ 部署函数;
④ 函数配置委托;
⑤ 函数配置触发器;
⑥ 函数添加依赖包;
⑦ 订阅模型并部署;
⑧ 制作动漫头像。
技术架构详解
-
FunctionGraph:
- FunctionGraph是华为云提供的无服务器计算服务,支持多种编程语言(如Python、Node.js等),使得开发者可以专注于业务逻辑开发,而无需关心服务器管理和扩展。
- 在本项目中,我们使用Python编写函数来处理HTTP请求,解析上传的图片文件,并调用ModelArts API进行图像处理。
-
ModelArts:
- ModelArts是一个一站式AI开发平台,提供从数据标注到模型训练、部署的一整套工具和服务。
- 我们选择了预训练的“人像动漫化”模型,并对其进行微调以更好地适应特定需求。之后,我们将此模型部署为在线推理服务,供FunctionGraph调用。
-
API Gateway:
- API Gateway用于创建、发布、维护和监控API,它能有效地管理API的安全性、访问控制和流量限制。
- 在本案例中,API Gateway充当了前端接口层,负责接收用户的请求,并将其转发给后端的FunctionGraph函数。
-
OBS (Object Storage Service):
- OBS提供了高可靠性和高性能的对象存储服务,适用于存储静态资源,如图片、视频等。
- 用户上传的原始图片以及生成的动漫化结果都将保存在OBS中,以便后续查看或下载。
-
IAM (Identity and Access Management):
- IAM用于定义和管理对华为云资源的访问权限,确保只有授权用户才能执行特定操作。
- 在部署过程中,我们需要设置适当的IAM策略,以保证安全性和合规性。
部署流程详细说明
环境准备
-
注册华为云账号: 如果还没有华为云账号,请先注册一个新账号,并完成实名认证。华为云有免费体验赠送的云主机哟,这里我们需要进入云主机。
-
打开CodeArts IDE: 进入云主机后 ,打开CodeArts IDE.
-
安装FunctionGraph插件: 点击右侧“扩展”搜索“CodeArts FunctionGraph”点击安装该插件。
-
创建函数: 打开插件,在插件窗口点击“…”选择“创建函数”,选择Http Function函数。
-
选择Hello World: 这里根据引导直接选择Hello World即可。
-
定义函数名: 这里我们定义函数名为carton-generation。
-
选择工程路径: 选择工程路径,选择后插件会在该路径下创建carton-generation工程。
-
创建新文件夹: 打开工程目录,创建新文件夹:templates。
-
创建文件: 在templates中创建文件index.html。
-
编辑代码: 编辑index.html代码,如下图所示(这里我参照了官方引导代码,就不复制下来了):
*这里代码有点长,还用不习惯这里的格式排布,大家可以复制代码到IDE去重新整理下:
<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>
-
删除app.py: 删除index.js,创建新文件app.py。
-
修改app.py代码: 修改app.py内容如下:(这里我代码就不复制下来了)。
-
修改bootstrap文件内容: 修改bootstrap文件内容如下,这可一定不要忘记改了。
/opt/function/runtime/python3.6/rtsp/python/bin/python3 $RUNTIME_CODE_ROOT/app.py
-
部署函数: 接下来我们就可以回到插件页面,选择部署函数。部署的时候我们选择新建的函数下的yml文件。
-
地区选择: 地区的话选择部署环境选择“华北-北京四”。
-
部署等待:等待部署成功。
点击“选择要展示的Region”,选择“华北-北京四”,可以看到该区域下刚部署好的函数:
carton-generation
。
-
打开函数: 接下来右键选择函数,点击浏览器打开,跳转到函数详情界面。
-
函数配置委托: 打开创建委托页面地址:
https://console.huaweicloud.com/iam/?agencyId=9525e901e4a44845bf64b4aec74d7be7®ion=cn-north-4&locale=zh-cn#/iam/agencies/create
输入委托名称、委托类型选择“云服务”、云服务选择“函数工作流FunctionGraph”。
-
配置权限:配置权限,选择ModelArts FullAccess(这里可以直接搜索)。
-
完成授权:完成授权后会出现以下结果:
-
函数配置委托:回到浏览器函数详情界面,点击“设置”,选择“权限”,“函数配置委托”选择提前创建好的委托,点击“保存”。
-
函数配置触发器: 点击“创建触发器”,选择“触发器类型”,选择“分组”(如果没有分组需先创建),选择“安全认证”,设置“后端超时”。
-
函数添加依赖包1: 返回“函数工作流”管理界面,选择“依赖包管理”,点击“创建依赖包”。
-
函数添加依赖包2: 填写“依赖包名称”,代码包上传方式为“从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”。
-
添加依赖包:进入函数详情页底部,点击“添加依赖包”。选择“私有依赖包”,依赖包名称如图所示。
-
订阅模型并部署AI应用:在华为云控制台点击搜索框搜索“ModelArts ”,点击“ModelArts”,选择“AI Gallery”。
-
头像动漫化模型:导航栏选择“模型”,搜索框输入“动漫”,选择“头像动漫化模型”。
-
ModelArts部署:进入详情页,点击“部署”,选择“ModelArts”。
-
ModelArts云服务:选择ModelArts的云服务区域。
-
创建委托:跳转到订阅应用列表,如果页面提示需要创建委托,根据指引创建即可。
-
部署:委托创建成功后订阅应用列表,点击“部署”。准备就绪后,点击右侧弹窗“部署”按钮,选择“在线服务”。
-
资源配置:资源池选择“公共资源池”,AI应用及配置选择“订阅应用”,选择AI应用及版本,计算节点规格选择“[限时免费]CPU:1核4GB”,勾选“我已阅读并同意以上内容”,点击“下一步”。
-
提交部署:点击“提交”(调后需要耐心等待部署进度)。
-
运行服务:确认服务处于运行中状态,复制API接口公网地址备用。
-
环境变量:回到函数页面,设置环境变量,键:MODEL_ART_API,值:刚刚复制的API接口公网地址。
-
制作动漫头像:到这里函数和AI应用就已经部署好了,可以复制URL到浏览器打开web页面开始制作动漫头像。
-
来看看效果吧:至此该实验已完成,我们看看动漫头像效果吧!
结果与影响
通过本次实践,我们不仅成功构建了一个高效、易用的智能头像动漫化处理应用,还展示了云计算与AI技术相结合的强大潜力。该方案不仅可以应用于社交媒体、游戏等领域,还可以进一步探索更多基于AI的图像处理应用场景,为用户提供更加个性化和有趣的互动体验。同时,借助华为云提供的丰富工具集和服务,开发者可以在短时间内完成复杂项目的开发与部署,降低了技术门槛的同时也提升了项目的灵活性和响应速度。
这篇文章我尽可能详尽地描述了如何结合FunctionGraph和ModelArts来实现智能头像动漫化处理的应用,特别是针对部署流程进行了详细的说明。希望这些信息能帮助您更深入地理解和实施该项目。
我正在参加【有奖征集 第34期】华为开发者空间一行代码快速上云,参与视频、文章投稿赢2000元开发者礼包。
链接:https://bbs.huaweicloud.com/blogs/438987
- 点赞
- 收藏
- 关注作者
评论(0)