愿我们终有重逢之时,而你还记得我们曾经讨论的话题。
group 868373192
second group 277356808
1. 导入库
import gradio as gr
from PIL import Image
from modelscope_studio import encode_image, decode_image, call_demo_service
import json
import os
from skimage import io
import numpy as np
-
gradio: 用于创建交互式Web界面的库。
-
PIL: Python Imaging Library,用于图像处理。
-
modelscope_studio: 自定义库,包含图像编码、解码和调用模型服务的功能。
-
json: 用于处理JSON数据。
-
os: 用于处理文件路径。
-
skimage.io: 用于读取图像。
-
numpy: 用于数值计算。
2. 定义推理函数 inference
def inference(image: Image, bk: Image) -> Image:
if image is None or bk is None:
return None, None
input_url = encode_image(image)
data = {
"task": "portrait-matting",
"inputs": [
input_url
],
"urlPaths": {
"inUrls": [
{
"value": input_url,
"fileType": "png",
"type": "image",
"displayType": "ImgUpload",
"displayProps": {
"label": {
"text": "原图",
"style": {
"background": "rgba(98,74,255,0.8)",
"color": "#fff"
}
}
},
"validator": {
"max_resolution": "3000*3000",
"max_size": "10M"
},
"name": "",
"title": ""
}
],
"outUrls": [
{
"outputKey": "output_img",
"type": "image"
}
]
}
}
model_id = 'cv_unet_image-matting'
result = call_demo_service(path='damo', name=model_id, data=json.dumps(data))
print(result)
res_url = result['data']['output_img']
res_img = io.imread(res_url)
alpha = res_img[:, :, 3:4] / 255.0
w, h = image.size
bk = bk.resize((w, h))
combine_img = image * alpha + bk * (1 - alpha)
combine_img = combine_img.astype(np.uint8)
return res_img, combine_img
-
功能: 该函数接收两张图像(人像和背景),使用模型对输入的人像进行抠图,然后将抠图结果与背景图像进行合成,生成新的图像。
-
步骤:
-
检查输入: 确保输入图像不为空。
-
图像编码: 将输入图像编码为URL。
-
构建请求数据: 构建包含任务类型、输入图像URL等信息的JSON数据。
-
调用模型服务 : 使用
call_demo_service
函数调用模型服务进行抠图。 -
读取结果: 从模型服务返回的结果中获取抠图结果的URL,并读取该图像。
-
处理图像: 提取抠图结果的Alpha通道,调整背景图像大小,将抠图结果与背景图像合成。
-
返回结果: 返回抠图结果和合成后的新图像。
-
3. 定义Gradio界面
css_style = "#fixed_size_img {height: 240px;} " \
"#overview {margin: auto;max-width: 400px; max-height: 400px;}"
title = "一键人像抠图换背景"
description = "输入一张人像照片和背景图,本空间能生成抠图结果,并进行换背景,一键穿越!欢迎使用!"
examples = [[os.path.dirname(__file__) + 'input1.jpg', os.path.dirname(__file__) + 'bk1.jpg'],
[os.path.dirname(__file__) + 'input2.jpg', os.path.dirname(__file__) + 'bk2.jpg'],
[os.path.dirname(__file__) + 'input3.jpg', os.path.dirname(__file__) + 'bk3.jpg']]
with gr.Blocks(title=title, css=css_style) as demo:
gr.HTML('''
<div style="text-align: center; max-width: 720px; margin: 0 auto;">
<div
style="
display: inline-flex;
align-items: center;
gap: 0.8rem;
font-size: 1.75rem;
"
>
<h1 style="font-family: PingFangSC; font-weight: 500; font-size: 36px; margin-bottom: 7px;">
一键人像抠图换背景
</h1>
''')
gr.Markdown(description)
with gr.Row():
img_input1 = gr.Image(label="人像", type="pil", elem_id="fixed_size_img")
img_output1 = gr.Image(label="抠图", type="pil", elem_id="fixed_size_img")
with gr.Row():
img_input2 = gr.Image(label="背景", type="pil", elem_id="fixed_size_img")
img_output2 = gr.Image(label="新图", type="pil", elem_id="fixed_size_img")
with gr.Row():
btn_submit = gr.Button(value="一键抠图换背景", elem_id="blue_btn")
# btn_clear = gr.Button(value="清除")
examples = gr.Examples(examples=examples, inputs=[img_input1, img_input2], outputs=[img_output1, img_output2])
btn_submit.click(inference, inputs=[img_input1, img_input2], outputs=[img_output1, img_output2])
demo.launch()
-
功能: 创建一个Gradio界面,允许用户上传人像和背景图像,并展示抠图结果和合成后的新图像。
-
界面元素:
-
标题: 显示"一键人像抠图换背景"。
-
描述: 显示功能的简要说明。
-
输入框: 用户上传人像和背景图像。
-
输出框: 显示抠图结果和合成后的新图像。
-
按钮 : 用户点击按钮后,调用
inference
函数进行抠图和合成。 -
示例: 提供一些示例图像供用户参考。
-
4. 启动Gradio界面
demo.launch()
- 功能: 启动Gradio界面,用户可以在浏览器中访问并使用该工具。
总结
该代码实现了一个基于Gradio的Web界面,用户可以通过上传人像和背景图像,使用预训练的模型进行人像抠图,并将抠图结果与背景图像合成,生成新的图像。界面简洁直观,适合用于展示和体验人像抠图换背景的功能。