Amazon SageMaker 轻松“拿捏”各式风格图片融合,激发无限创意!

322350962748aecbc74ddd84811e69b8.gif

图像融合技术广泛应用于多个行业,如电商营销素材、广告创意。其目标是将前景插入到背景图像中,通过解决外观、几何和语义上的不一致性,实现逼真和谐的合成图像。

生成式 AI 在为商品生成背景时,常常会对商品整体进行修改,导致出现“货不对版”。而这一问题现在可以通过图片融合工具库 Libcom(the library of image composition)解决了。该工具库提供了各种图片融合场景所需的模型,这些预训练模型开箱即用,用户还可以利用自有风格的数据进行进一步训练,以满足特定效果。

Amazon SageMaker 是一个亚马逊云科技托管的机器学习平台,可用于为使用场景构建、训练和部署模型。Notebook 实例为构建机器学习模型提供了灵活的环境,省去了用户在管理底层计算基础设施上花费的时间和精力。本文将介绍如何在 Amazon SageMaker 上部署 Libcom 图片融合模型。

a4d40bafa5da1aeed62d9d512adb0a3a.png

Amazon SageMaker

扫码了解更多

方案总览

39ea05e1b782063ee88d29efbf2c5713.png

上图是在 Amazon SageMaker 上搭建和使用 Libcom 模型的整体架构。本文采用 BYOC(Bring Your Own Container)的方式,也就是将现有代码构建成自定义 Docker 镜像的方式迁移到 Amazon SageMaker,适合于现有代码与依赖库的关系比较复杂的情况。

首先我们使用一个亚马逊云科技账号,具有访问 Amazon CloudFormation 和 Amazon SageMaker 的权限。登陆亚马逊云科技控制台后,以 us-east-1 区为例,选择打开 Amazon CloudFormation 服务,点击 Create Stack(with new resource),上传模版文件,通过自动化的方式部署本次实验所需要的环境和代码。

3712bb066abe11c3f46a3862cdd7f82b.png

亚马逊云科技控制台

扫码了解更多

8fb3d5680530785e9fa53d77d1048c4e.png

模版文件

扫码了解更多

左右滑动查看更多

e5c1a66d47120f93c595662a5747c38a.png

点击下一步,输入 Stack Name

96c5ef926275d8b99be647390460d662.png

确认创建 IAM Resource 后提交

bd4ba2aff824e41ed8ed6af673a503dd.png

等待几分钟 Amazon CloudFormation Stack 创建完成后,会提供一个 Notebook 实例,实例上已包含克隆好的初始化代码

16f75ebebb56197bfedbe298c4684748.png

在亚马逊云科技的 Console 里选择 Amazon SageMaker 服务,在左边导航栏打开 Notebook Instance,找到创建好的 Notebook Instance: libcom-sm-notebook,点击 Open JupyterLab 打开 Notebook 实例,进到 host-libcom-on-sagemaker-endpoint 目录后,看到两个 Notebook:

  • deploy.ipynb:负责下载模型、打包推理代码、构建镜像、创建在线推理端点和实验结束后的资源清理

  • predict.ipynb:提供了样图的测试步骤和结果展示

创建 Amazon SageMaker

 Libcom Endpoint

按照 deploy.ipynb 中的步骤顺序执行即可。本文使用 Libcom 提供的两种模型:

  • FOPAHeatMapModel 基于一对前景-背景图,预测所有位置的合理性分数,输出最佳位置的合成图像

  • ImageHarmonizationModel 调整前景照明,使其与背景相匹配

为节约推理时间,我们提前将模型下载到本地,和推理代码一起打包到镜像中

# download models
!chmod +x download_pretrained_model.sh && bash download_pretrained_model.sh

左右滑动查看更多

下载完成后,把模型和推理代码打包成镜像,推送到 Amazon ECR

# build containers used by sageMaker
!chmod +x build_and_push.sh && bash build_and_push.sh $region_name

左右滑动查看更多

因为是 BYOC 模式,需要遵循 Amazon SageMaker Hosting 定义的一套镜像构建范式,重点说明如下,细节请参考代码文件。

  • 容器启动命令,参考代码中的 serve 文件

docker run image serve
  • 容器应用的心跳检测服务

@app.route('/ping', methods=['GET'])
def ping():
    #Determine if the container is working and healthy. In this sample container
    # Declare it healthy if we can load the model successfully."""
    # health = ScoringService.get_model() is not None 
    status = 200 #if health else 404
    return flask.Response(response='\n', status=status, mimetype='application/json')

左右滑动查看更多

  • 容器应用的心跳检测服务

import flask
. . .
app = flask.Flask(__name__)
. . .
@app.route('/invocations', methods=["POST"])
def invoke(request):
    # model() is a hypothetical function that gets the inference output:
    resp_body = model(request)
    return flask.Response(resp_body, mimetype='text/plain')

左右滑动查看更多

详细的推理服务参考 Libcom/libcom/predictor.py 中的定义,本次推理代码允许用户输入 4 种方法,将在下一章测试环节详细展开说明。

Libcom/libcom/predictor.py 部分内容:

@app.route('/invocations', methods=['POST'])
def transformation():
    data = json.loads(flask.request.data)
    function_name = data.get("function",None)
    if function_name == "heatmap_compose":
        result = heatmap_compose(data)
    elif function_name == "simple_compose":
        result = simple_compose(data)
    elif function_name == "pct_mode":
        result = pctnet(data)
    elif function_name == "cdt_mode":
        result = cdtnet(data)

左右滑动查看更多

部署成功后,在 

Amazon SageMaker→Endpoints 观测到 Endpoint 处于 InService 状态

63c59e03d1e4a12899d06c863f748b2d.png

测试 Amazon SageMaker

 Libcom Endpoint

打开 predict.ipynb 根据提供的步骤顺序执行即可。

在图片融合场景中,我们需要向模型提供前景物体的信息,以便进行图片的合成和和谐化处理。为了实现这一目标,我们使用蒙版来标记前景物体。蒙版的获取方法有很多种,其中最常见的是使用 SAM(Segment Anything Model),本文不再详述。

1、热力图与最佳放置位置

将准备的前景图模特,模特蒙版和背景图卧室组成请求体发送给推理端点。推理服务会根据前景图和背景图包含的信息,生成一张热力图,热力图中高亮的位置表示背景图的最佳放置位置。基于热力图的生成结果,定制推理代码取了热力图最亮的点,作为背景图中最适合放置前景的位置,执行图片合成。

adc10e4513c3b302ddeeb4905ad44cca.jpeg

## Generate FOPA image and placement suggestion
background_path = "uploads/bg.png"
foreground_path = "uploads/fg.jpg"
foreground_mask_path = "uploads/fg_mask.png"
bg=encode_image(background_path)
fg=encode_image(foreground_path)
fg_mask=encode_image(foreground_mask_path)
function = "heatmap_compose"
payload = {
    "function":function,
    "background":bg,
    "foreground":fg,
    "foreground_mask":fg_mask,
    "scale_x":0.8
}
# Prepare the request body as a JSON object
request_body = json.dumps(payload)
# Send the inference request to the endpoint
response = client.invoke_endpoint(
    EndpointName=endpoint_name,
    Body=request_body,
    ContentType="application/json"
)
# Parse the response
response_body = response["Body"].read().decode("utf-8")
fopa_result = json.loads(response_body)
bbox=fopa_result['bboxes']
print(bbox)
heatmap=save_image_from_base64(fopa_result['heatmap_image'],'results','heatmap')
comp_img=save_image_from_base64(fopa_result['comp_image'],'results','comp_img')
comp_mask=save_image_from_base64(fopa_result['comp_mask'],'results','comp_mask')
grid_img  = make_image_grid([heatmap, comp_img, comp_mask])
from IPython.display import display,Image
cv2.imwrite(heatmap, grid_img)
display(Image(filename=heatmap))

左右滑动查看更多

根据热力图放置效果:

ee2d5ff5c035970de8a62f23d20a259d.png

测试阶段用户可能会调整合并的位置,推理代码中提供用户自定义位置 bbox 放置前景图片。

# prepare images
background_path = "uploads/bg.png"
foreground_path = "uploads/fg.jpg"
foreground_mask_path = "uploads/fg_mask.png"
bg=encode_image(background_path)
fg=encode_image(foreground_path)
fg_mask=encode_image(foreground_mask_path)
function = "simple_compose"
bbox = [376, 187, 550, 791]
print(bbox)
payload = {
    "function":function,
    "background":bg,
    "foreground":fg,
    "foreground_mask":fg_mask,
    "bbox":bbox
}
# Prepare the request body as a JSON object
request_body = json.dumps(payload)
# Send Image Compose inference request to the endpoint
response = client.invoke_endpoint(
    EndpointName=endpoint_name,
    Body=request_body,
    ContentType="application/json"
)
# Parse the response
response_body = response["Body"].read().decode("utf-8")
compose_result = json.loads(response_body)
# Process the result
#decode_image(compose_result['comp_image'])
#decode_image(compose_result['comp_mask'])
comp_image=save_image_from_base64(compose_result['comp_image'],'results','comp_image')
comp_mask=save_image_from_base64(compose_result['comp_mask'],'results','comp_mask')
grid_img  = make_image_grid([comp_image, comp_mask])
from IPython.display import display,Image
cv2.imwrite(comp_image, grid_img)
display(Image(filename=comp_image))

左右滑动查看更多

根据指定坐标放置效果:

db24e8b9ebb97799c7dd4d7a0483a9b7.png

大家会注意到,每次合成图片后,服务端还会返回一张合成图的前景位置蒙版,这是用于给合成图片做后续光影和谐处理的输入使用。

2、图片合成后的和谐化

Libcom 提供了两种和谐化算法,PCTNet(像素预测变换)和 CDTNet(像素和谐变换),供不同的场景和实际效果选用。

f827cd8e190b70d439942cac125f3ace.png

PCTNet

(像素预测变换)

扫码了解更多

4c0aa6a64c31355b266492bb09129163.png

CDTNet

(像素和谐变换)

扫码了解更多

左右滑动查看更多

使用 CDTNet:

# choose cdt mode
comp_image_path = "uploads/comp_image.png"
comp_mask_path = "uploads/comp_mask.png"
comp_image=encode_image(comp_image_path)
comp_mask=encode_image(comp_mask_path)
function = "cdt_mode"
payload = {
    "function":function,
    "comp_image":comp_image,
    "comp_mask":comp_mask
}
#payload
# Prepare the request body as a JSON object
request_body = json.dumps(payload)
# Send the inference request to the endpoint
response = client.invoke_endpoint(
    EndpointName=endpoint_name,
    Body=request_body,
    ContentType="application/json"
)
# Parse the response
response_body = response["Body"].read().decode("utf-8")
harmony_result = json.loads(response_body)
harmony_image=save_image_from_base64(harmony_result['cdt_result'],'results','harmony')
grid_img  = make_image_grid([comp_image_path, harmony_image])
from IPython.display import display,Image
cv2.imwrite(harmony_image, grid_img)
display(Image(filename=harmony_image))

左右滑动查看更多

使用 CDTNet 的效果(左侧模特原图,右侧 CDTNet 效果图):

ebb4d91900eec3dd7a8e7b7ff9a6e436.png

使用 PCTNet 的效果(左侧模特原图,右侧 PCTNet 效果图):

20e4e6c9340a4ce9ffb2fdcfa1dd60de.png

在 PCTNet 预训练模型中,我们注意到在预测室内光源后,人物的暗色调被过度强调,不太符合人物和谐化的场景。然而,在下面的商品处理示例中表现的就更自然。

(左侧香水合成到背景的原图,右侧对香水瓶做 PCTNet 和谐化效果图)

fbcf09bbd32757cf36ccee2f9fd2b50b.png

资源清理

实验结束后,执行 deploy.ipynb 中的代码,清理资源,避免浪费

# delete endpoint for cost saving
endpoint_name = 'libcom'
model_name='libcom'
import boto3
sagemaker_client = boto3.client("sagemaker")
# Delete the endpoint
sagemaker_client.delete_endpoint(EndpointName=endpoint_name)
# Delete the endpoint configuration
sagemaker_client.delete_endpoint_config(EndpointConfigName=endpoint_name)
# Delete the model
sagemaker_client.delete_model(ModelName=model_name)

左右滑动查看更多

总结

生成式 AI 的出现极大地提高了我们创造创意、尝试新风格的效率。然而,在商品展示等场景中,真实性仍然是一个不可或缺且至关重要的需求。本文演示了如何在 Amazon SageMaker 上部署 Libcom 图片融合服务,借助 Amazon SageMaker 提供的完全托管、可扩展的基础设施,轻松满足各种规模的生产负载需求。

参考链接

c704600287a0d90dae822d43fbee4872.png

本文代码

扫码了解更多

8aa701ce3419f87c76267976158b569b.png

Libcom 项目

扫码了解更多

ff191426357c092d9e2e8b35be6b0361.png

Amazon SageMaker –

bring your algorithms inference code

扫码了解更多

左右滑动查看更多

本篇作者

8b596fd52cde65b5f1472e155045d72f.jpeg

林益龙

亚马逊云科技解决方案架构师,专注于在企业中推广云计算与人工智能的最佳实践。曾担任运维经理、解决方案架构师等岗位,拥有多年的企业 IT 运维和架构设计经验。

3396967e6d7764ee441b8a0190d8e54d.jpeg

罗新宇

亚马逊云科技解决方案架构师,在架构与开发领域有非常丰富的实践经验,目前致力于 Serverless 在云原生架构中的应用。

90746cfbc0cec90a00431c6316198575.png

ae0be9704b0cdb8da775bbbd00335381.gif

星标不迷路,开发更极速!

关注后记得星标「亚马逊云开发者」

点击阅读原文查看博客,获得更详细内容

听说,点完下面4个按钮

就不会碰到bug了!

ed3f5e195a974caf2e35cadea8dffb95.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值