一键AI抠图,证件照换背景,可部署成自己的应用

1 开发背景

AI抠图技术已经非常成熟,并且有效果非常好的开源模型。 日常中可以用于替换证件照背景

但是网上许多的证件照替换背景 竟然需要收费

鉴于此,便将目前最好的(SOTA)开源抠图模型 BRIA Background Removal v1.4 Model 进行部署

也可以直接体验部署好的应用

点击链接体验应用

 

2 项目内容

  1. 展示如何配置环境,这种配置环境的方法是所有项目通用的,配置一次就可以,做到一劳永逸

  2. 展示如何调用模型,进行背景的抠去和背景颜色的替换

  3. 最后展示了如何将该项目 部署成一个应用,这个应用比较简单,也是具有教学意义

3 配置环境

In [ ]

# 配置环境(第一次运行次项目的时候配置即可,之后无需安装)

# 安装包
!mkdir /home/aistudio/external-libraries
!pip install  onnxruntime scikit-image -i https://mirrors.aliyun.com/pypi/simple/ \
     -t /home/aistudio/external-libraries

In [1]

# 设置环境变量 (每次重新进入此项目或者重启内核后,都要执行此代码)

# 在py文件里面运行环境
import sys 
sys.path.append('/home/aistudio/external-libraries')

# 在ipynb里面运行环境
import os
os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', '')  + ':/home/aistudio/external-libraries'

4 定义remove background的函数

In [2]

# 在py文件里面运行环境
import sys 
sys.path.append('/home/aistudio/external-libraries')

# 在ipynb里面运行环境
import os
os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', '')  + ':/home/aistudio/external-libraries'

import onnxruntime as ort
import cv2
import numpy as np
from PIL import Image, ImageDraw
import re
from skimage import io

class BriaRMBG_ONNX:
    def __init__(self, model_path):
        self.session = ort.InferenceSession(model_path)
    
    def __call__(self, input_tensor):
        input_name = self.session.get_inputs()[0].name
        outputs = self.session.run(None, {input_name: input_tensor})
        return outputs

def preprocess_image(im: np.ndarray, model_input_size: list) -> np.ndarray:
    if len(im.shape) < 3:
        im = cv2.cvtColor(im, cv2.COLOR_GRAY2BGR)  # 将灰度图像转换为BGR格式
    im = cv2.resize(im, model_input_size, interpolation=cv2.INTER_LINEAR)  # 调整图像大小
    im = im.astype(np.float32)  # 将图像数据类型转换为float32
    im /= 255.0  # 归一化到[0, 1]范围
    mean = [0.5, 0.5, 0.5]
    std = [1.0, 1.0, 1.0]
    im -= mean
    im /= std
    return im[np.newaxis, :, :, :]

def postprocess_image(result: np.ndarray, im_size: list) -> np.ndarray:
    result = result[0]  # 移除batch维度
    ma = np.max(result)
    mi = np.min(result)
    result = (result - mi) / (ma - mi)  # 归一化到[0, 1]范围
    result = (result * 255).astype(np.uint8)  # 将数据类型转换回uint8
    result = cv2.resize(result, [im_size[1], im_size[0]], interpolation=cv2.INTER_LINEAR)  # 调整图像大小
    return result


def add_background_to_image(input_image_path, output_image_path, background_color, out_size=None):
    """
    给透明背景的PNG人像图像添加任意颜色的背景。

    :param input_image_path: 输入图像的路径
    :param output_image_path: 输出图像的路径
    :param background_color: 背景颜色 (R, G, B)
    :param size: 输出图像的大小 (width, height) 默认与输入图像相同
    """
    # 打开输入图像
    image = Image.open(input_image_path)

    # 如果图像不是PNG格式,先转换为PNG
    if image.format != 'PNG':
        image = image.convert('RGBA')
    
    if out_size is None:
        out_size = image.size

    image
    out_image = Image.new('RGB', image.size, background_color)
    out_image.paste(image, (0,0), image)

    out_image.resize(out_size)

    # 保存新的图像
    out_image.save(output_image_path)

def rmbg(input_image_path,  background_color, out_size_w, out_size_h, size_opt):

    if size_opt == "保持原图大小":
        shape = cv2.imread(input_image_path).shape
        out_size = (int(shape[0]),int(shape[1]))
    else:
        out_size = (int(out_size_w), int(out_size_h))

    match = re.search(r'^(.+/)([^.]+)(\..+)$', input_image_path) # 使用正则表达式找到图片名称和扩展名
    path, filename, ext = match.groups() # 获取组:路径、文件名、扩展名
    new_filename = filename + "_rmgb" + ext # 修改文件名
    out_path = path + new_filename # 抠图
    new_filename = filename + "_bg" + ext
    output_image_path = path + new_filename # 证件照

    net = BriaRMBG_ONNX(f"/home/aistudio/rmbg/onnx/model.onnx" )

    # prepare input
    model_input_size = [1024,1024]
    orig_im = io.imread(input_image_path)
    orig_im_size = orig_im.shape[0:2]
    image = preprocess_image(orig_im, model_input_size)
    image = np.transpose(image, (0, 3, 1, 2))  # ONNX通常需要CHW格式

    # inference
    result = net(image)
    
    # post process
    result_image = postprocess_image(result[0][0], orig_im_size)

    # save result
    pil_im = Image.fromarray(result_image)
    no_bg_image = Image.new("RGBA", pil_im.size, (0,0,0,0))
    orig_image = Image.open(input_image_path)
    no_bg_image.paste(orig_image, mask=pil_im)
    no_bg_image.save(out_path)

    print(background_color, out_size)
    add_background_to_image(out_path, output_image_path, background_color, out_size)

    return out_path, output_image_path

5 调用函数进行抠图

In [3]

import cv2
import matplotlib.pyplot as plt



# 输入图片的路径
input_img = '/home/aistudio/rmbg/photo/wj.png'

# 证件照的背景颜色
# color = "#FFFFFF" # 白色(用于护照、签证、身份证等)
color = "#438EDB" # 蓝色(用于毕业证、工作证等)
# color = "#FF0000" # 红色(用于一些特殊的证件照)

# 证件照的大小
width = 295
height = 413  # 一寸(295像素 x 413像素)

# 是否保持原图大小 
# size_opt = "不保持原图大小"
size_opt = "保持原图大小" # 如果选了这个会保持输入图片的大小,忽略上面的 证件照的大小 参数



# color, width, height 这三个参数不影响抠图,只会影响证件照的结果
out_path, output_image_path = rmbg(input_img, color, width, height, size_opt)

print('抠图后的图片: ', out_path)
print('证件照: ', output_image_path)

#438EDB (1024, 1596)
抠图后的图片:  /home/aistudio/rmbg/photo/wj_rmgb.png
证件照:  /home/aistudio/rmbg/photo/wj_bg.png

6 结果展示

In [4]

# 展示图片

from PIL import Image
import matplotlib.pyplot as plt

# print('原图')
image_input = Image.open(input_img)

# print('抠图后的图片')
image_rmbg = Image.open(out_path)

# print('证件照')
image_bg = Image.open(output_image_path)


# 设定图片显示的大小
fig, axs = plt.subplots(3, 1, figsize=(5, 15))

# 在每个子图上显示一张图片
axs[0].imshow(image_input)
axs[0].axis('off')  # 不显示坐标轴
axs[0].set_title(' original')

axs[1].imshow(image_rmbg)
axs[1].axis('off')  # 不显示坐标轴
axs[1].set_title(' remove background')

axs[2].imshow(image_bg)
axs[2].axis('off')  # 不显示坐标轴
axs[2].set_title('with background')

# 调整子图之间的间距
plt.tight_layout()

# 显示画布
plt.show()

<Figure size 500x1500 with 3 Axes>

7 部署自己的应用

应用的代码我已经写好了 /home/aistudio/untitled.gradio.py

直接点击右上角的“部署” 即可,步骤如下


分割线

图片1

 

图片2

 

图片3

 

图片4

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【AIGC-数字人】V-Express:渐进式训练的数字人视频生成技术

介绍 在人像视频生成领域&#xff0c;使用单张图像生成人像视频已经变得越来越普遍。一种常见的方法涉及利用生成模型来增强适配器以实现受控生成。然而&#xff0c;控制信号的强度可能会有所不同&#xff0c;包括文本、音频、图像参考、姿态、深度图等。其中&#xff0c;较弱的…

奇偶校验位

描述 题目描述&#xff1a; 现在需要对输入的32位数据进行奇偶校验,根据sel输出校验结果&#xff08;1输出奇校验&#xff0c;0输出偶校验&#xff09; 信号示意图&#xff1a; 波形示意图&#xff1a; 输入描述&#xff1a; 输入信号 bus sel 类型 wi…

gitlab之cicd的gitlab-runner集成-dockerfile构建环境

目录 概述离线资源docker-compose问题 docker-compose问题1问题2 gitlab-runner集成gitlab 概述 cicd引文目录是想通过dockerfile构建 maven、jdk、docker环境的 gitlab-runner 运行环境。但docker最后测试的时候有点问题&#xff0c;且最后使用 kubectl 时有麻烦&#xff0c;所…

牛客网刷题 | BC103 金字塔图案

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 KiKi学习了循环&am…

共计3万字!从零开始创建一个小规模的稳定扩散模型!

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学。 针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 合集&#x…

知识运维概述

文章目录 知识运维研究现状技术发展趋势 知识运维 由于构建全量的行业知识图谱成本很高&#xff0c;在真实的场景落地过程中&#xff0c;一般遵循小步快走、快速迭代的原则进行知识图谱的构建和逐步演化。知识运维是指在知识图谱初次构建完成之后&#xff0c;根据用户的使用反馈…

“手撕”链表的九道OJ习题

目录 1. 第一题 2. 第二题 3. 第三题 4. 第四题 5. 第五题 6. 第六题 7. 第七题 8. 第八题 9. 第九题 1. 第一题 删除链表中等于给定值 val 的所有节点。OJ链接 思路如下&#xff1a; 相当于链表的removeAll();制定prev和cur&#xff0c;prev记录前一个节点&#xff…

2024最新VMware Workstation Pro下载教程

自从2024年5月份之后&#xff0c;VMware workstation player就不能直接在vm官网下载,需要到broadcom博通网站上下载 下面介绍最新下载步骤&#xff1a; 百度直接搜索vmware 进入官网点击Workstation Pro链接 博通注册对应的账号 现在下载都需到博通注册对应的账号 登录邮…

网络原理-TCP/IP --应用层

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 今天你敲代码了吗 目录 3.网络原理 -TCP/IP3.1 应用层 3.网络原理 -TCP/IP 3.1 应用层 应用层是程序员打交道最多的一层,与应用程序直接相关 而应用层的协议,实际上就规定了你写的程序,通过网络传输的时候,按…

使用 Scapy 库编写 IP 地址欺骗攻击脚本

一、介绍 1.1 概述 IP地址欺骗&#xff08;IP Spoofing&#xff09;是一种网络攻击技术&#xff0c;攻击者伪造其数据包的源IP地址&#xff0c;使其看起来像是从其他合法地址发送的。这种技术常用于各种攻击中&#xff0c;例如DDoS攻击、Man-in-the-Middle&#xff08;MITM&a…

271 基于matlab的可调Q因子小波变换故障诊断

基于matlab的可调Q因子小波变换故障诊断&#xff0c;可用在轴承、齿轮、活塞等故障诊断中&#xff0c;程序中包含了原始TQWT工具箱和轴承振动信号信号的谱包络的求取。通过仿真数据、实际轴承数据说明了方法的效果。程序已调通&#xff0c;可直接运行。 271 可调Q因子小波变换 …

算法第三天力扣第69题:X的平方根

69. x 的平方根 (可点击下面链接或复制网址进行做题) https://leetcode.cn/problems/sqrtx/https://leetcode.cn/problems/sqrtx/ 给你一个非负整数 x ,计算并返回 x 的 算术平方根 。 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。 注意:不允许使用任何内…

Gavin Wood 访谈|Polkadot 从何而来,又将如何面对 AI 时代?

如果没有宏观经济&#xff0c;加密世界可能无法存在。或许&#xff0c;Satoshi Nakamoto 也永远不会写出那篇开创性的白皮书。区块链技术作为指数时代的核心之一&#xff0c;在宏观经济理论中占有重要地位。传统的经济增长公式是人口增长加生产率增长加债务增长。然而&#xff…

32【Aseprite 作图】石头——拆解

1 石头先画轮廓&#xff0c;还是2 4 1 1 2 2 2&#xff0c;这样画一个圆的轮廓 或者2 1 1 3 5 1 1 1 1 2 4 &#xff0c; 2 最暗一层的黑色&#xff0c;做阴影部分&#xff0c;就是7 4 3 2 做最深的部分 各个地方画一些浅色的&#xff0c;做高光部分&#xff0c;上面的高光偏圆…

依赖管理包介绍

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 相关组件 3. 示例代码4. 内容总结 我们在上一章回中介绍了"使用get进行依赖管理"相关的内容&#xff0c;本章回中将介绍如何使用get进行状态管理一.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 …

【计算机毕设】SpringBoot海滨体育馆管理系统设计与实现 - 源码免费(私信领取)

免费领取源码 &#xff5c; 项目完整可运行 &#xff5c; v&#xff1a;chengn7890 诚招源码校园代理&#xff01; 1. 引言 体育馆作为重要的体育场馆&#xff0c;承担着举办体育赛事、健身活动和文化演出等多种功能。为了提高体育馆的管理效率和服务质量&#xff0c;本项目旨在…

2024-05-31 blue-VH-driver-问题分析-有状态的服务-状态的处理

摘要: VH的driver对上层提供的接口&#xff0c;是会保持状态。这个状态&#xff0c;可以分为&#xff0c;查询的数据的状态&#xff0c;主要是为了提供翻页查询的功能。另一种状态&#xff0c;就是订阅。 有状态的服务: 状态是什么? 其实从调用方的角度更好的理解&#xff0c…

进程与线程(三)

进程与线程&#xff08;三&#xff09; 进程间通信传统间的进程间通信机制无名管道无名管道的特征无名管道的创建父子进程通信测试管道的大小管道读写易出现的问题 有名管道创建有名管道有名管道的写端代码有名管道的读端代码 信号信号的特征产生信号硬件来源软件来源发送信号的…

【MATLAB】概述1

非 ~ 注释 % 定义 >> 数组 赋值 赋值&#xff1a;>> x1 函数 数组 x[x1,x2] 行向量&#xff08;&#xff0c;or ) x[x1;x2] 列向量 x. 转置等间隔向量 1-10 向量&#xff1a;>>xlinspace(1,10,10) 矩阵 矩阵&#xff1a;>>A[1,2,3;4,5,6;7,8,9] …

重生之 SpringBoot3 入门保姆级学习(10、日志基础与使用)

重生之 SpringBoot3 入门保姆级学习&#xff08;10、日志基础使用&#xff09; 3.1 日志基础3.2 使用日志3.2.1 基础使用3.2.2 调整日志级别3.2.3 带参数的日志 3.1 日志基础 SpringBoot 默认使用 SLF4j&#xff08;Simple Logging Facade for Java&#xff09;和 Logback 实现…