first commit

This commit is contained in:
douboer
2026-01-20 13:44:28 +08:00
commit 57cd9a1f39
6 changed files with 505 additions and 0 deletions

258
remove_background.py Normal file
View File

@@ -0,0 +1,258 @@
"""
图片去背景工具
使用rembg库自动去除图片背景
"""
import os
import argparse
from pathlib import Path
from rembg import remove, new_session
from PIL import Image
# 支持HEIC格式
try:
from pillow_heif import register_heif_opener
register_heif_opener()
HEIC_SUPPORTED = True
except ImportError:
HEIC_SUPPORTED = False
def str2bool(v):
"""将字符串转换为布尔值"""
if isinstance(v, bool):
return v
if v.lower() in ('yes', 'true', 't', 'y', '1'):
return True
elif v.lower() in ('no', 'false', 'f', 'n', '0'):
return False
else:
raise argparse.ArgumentTypeError('布尔值应为true或false')
def remove_background(input_path, output_path, session=None, **kwargs):
"""
去除图片背景
Args:
input_path: 输入图片路径
output_path: 输出图片路径
session: rembg会话对象可选
**kwargs: 其他参数如alpha_matting相关参数
"""
print(f"正在处理: {input_path}")
# 读取输入图片
input_image = Image.open(input_path)
# 去除背景
output_image = remove(input_image, session=session, **kwargs)
# 保存输出图片
output_image.save(output_path)
print(f"已保存: {output_path}")
def process_images_folder(input_folder, output_folder, model_name="u2net",
alpha_matting=False, alpha_matting_foreground_threshold=240,
alpha_matting_background_threshold=10, alpha_matting_erode_size=10,
post_process_mask=False):
"""
批量处理文件夹中的所有图片
Args:
input_folder: 输入文件夹路径
output_folder: 输出文件夹路径
model_name: 模型名称,可选值:
- u2net (默认): 通用模型
- u2netp: 轻量版u2net
- u2net_human_seg: 人物分割
- silueta: 精简版u2net (43MB)
- isnet-general-use: 新的通用模型
- isnet-anime: 动漫角色高精度分割
- birefnet-general: 通用模型
- birefnet-portrait: 人像模型
alpha_matting: 是否启用alpha matting后处理改善边缘质量
alpha_matting_foreground_threshold: 前景阈值 (0-255),值越大保留越多前景
alpha_matting_background_threshold: 背景阈值 (0-255),值越大去除越多背景
alpha_matting_erode_size: 侵蚀大小,用于平滑边缘
post_process_mask: 是否启用mask后处理
"""
# 创建输出文件夹
Path(output_folder).mkdir(parents=True, exist_ok=True)
# 创建会话(重用会话可以提高性能)
print(f"使用模型: {model_name}")
session = new_session(model_name)
# 支持的图片格式
image_extensions = {'.jpg', '.jpeg', '.png', '.bmp', '.webp'}
if HEIC_SUPPORTED:
image_extensions.update({'.heic', '.heif'})
else:
print("提示: 未安装pillow-heifHEIC格式不可用。安装方法: pip install pillow-heif")
# 获取所有图片文件
input_path = Path(input_folder)
image_files = [f for f in input_path.iterdir()
if f.is_file() and f.suffix.lower() in image_extensions]
if not image_files:
print(f"{input_folder} 中没有找到图片文件")
return
print(f"找到 {len(image_files)} 张图片,开始处理...")
print(f"Alpha Matting: {'启用' if alpha_matting else '禁用'}")
if alpha_matting:
print(f" - 前景阈值: {alpha_matting_foreground_threshold}")
print(f" - 背景阈值: {alpha_matting_background_threshold}")
print(f" - 侵蚀大小: {alpha_matting_erode_size}")
print(f"Mask后处理: {'启用' if post_process_mask else '禁用'}")
print("-" * 50)
# 处理每张图片
for i, image_file in enumerate(image_files, 1):
try:
# 输出文件名保持原始名称改为PNG格式以支持透明背景
output_filename = image_file.stem + '_nobg.png'
output_path = Path(output_folder) / output_filename
print(f"[{i}/{len(image_files)}] ", end="")
remove_background(
str(image_file),
str(output_path),
session=session,
alpha_matting=alpha_matting,
alpha_matting_foreground_threshold=alpha_matting_foreground_threshold,
alpha_matting_background_threshold=alpha_matting_background_threshold,
alpha_matting_erode_size=alpha_matting_erode_size,
post_process_mask=post_process_mask
)
except Exception as e:
print(f"处理 {image_file.name} 时出错: {e}")
print("-" * 50)
print(f"处理完成!结果保存在 {output_folder} 文件夹中")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='图片去背景工具 - 使用rembg自动去除图片背景',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog='''
示例用法:
# 使用默认参数处理images文件夹
python remove_background.py
# 处理单个文件
python remove_background.py input.jpg output.png
# 处理指定文件夹
python remove_background.py my_images/ my_output/
# 使用不同模型
python remove_background.py input.jpg output.png -m birefnet-portrait
# 自定义alpha matting参数
python remove_background.py input.jpg output.png -ft 260 -bt 12 -es 5
'''
)
# 必需参数
parser.add_argument('input', nargs='?', default='images',
help='输入文件或文件夹路径(默认: images')
parser.add_argument('output', nargs='?', default=None,
help='输出文件或文件夹路径可选默认为output/')
# 模型选择
parser.add_argument('-m', '--model', default='isnet-general-use',
choices=['u2net', 'u2netp', 'u2net_human_seg', 'silueta',
'isnet-general-use', 'isnet-anime',
'birefnet-general', 'birefnet-general-lite',
'birefnet-portrait', 'birefnet-dis',
'birefnet-hrsod', 'birefnet-cod', 'birefnet-massive'],
help='选择使用的模型 (默认: isnet-general-use)')
# Alpha Matting参数
parser.add_argument('-a', '--alpha-matting', type=str2bool, nargs='?', const=True, default=True,
metavar='true/false',
help='启用alpha matting后处理默认: true。用法: -a 或 -a true 或 -a false')
parser.add_argument('-ft', '--foreground-threshold', type=int, default=245,
help='前景阈值 (0-255),值越大保留越多细节 (默认: 245)')
parser.add_argument('-bt', '--background-threshold', type=int, default=8,
help='背景阈值 (0-255),值越大去除越多背景 (默认: 8)')
parser.add_argument('-es', '--erode-size', type=int, default=2,
help='侵蚀大小,用于平滑边缘,值越大越平滑但可能丢失细节 (默认: 2)')
# 其他选项
parser.add_argument('-p', '--post-process', type=str2bool, nargs='?', const=True, default=True,
metavar='true/false',
help='启用mask后处理默认: true。用法: -p 或 -p true 或 -p false')
args = parser.parse_args()
print("=" * 50)
print("图片去背景工具")
print("=" * 50)
# 判断输入是文件还是文件夹
input_path = Path(args.input)
if not input_path.exists():
print(f"错误: 输入路径不存在: {args.input}")
exit(1)
# 处理单个文件
if input_path.is_file():
# 确定输出路径
if args.output is None:
output_path = input_path.parent / 'output' / (input_path.stem + '_nobg.png')
output_path.parent.mkdir(parents=True, exist_ok=True)
else:
output_path = Path(args.output)
output_path.parent.mkdir(parents=True, exist_ok=True)
print(f"输入文件: {input_path}")
print(f"输出文件: {output_path}")
print(f"模型: {args.model}")
print(f"Alpha Matting: {'启用' if args.alpha_matting else '禁用'}")
if args.alpha_matting:
print(f" - 前景阈值: {args.foreground_threshold}")
print(f" - 背景阈值: {args.background_threshold}")
print(f" - 侵蚀大小: {args.erode_size}")
print(f"Mask后处理: {'启用' if args.post_process else '禁用'}")
print("-" * 50)
# 创建会话
session = new_session(args.model)
# 处理图片
remove_background(
str(input_path),
str(output_path),
session=session,
alpha_matting=args.alpha_matting,
alpha_matting_foreground_threshold=args.foreground_threshold,
alpha_matting_background_threshold=args.background_threshold,
alpha_matting_erode_size=args.erode_size,
post_process_mask=args.post_process
)
print("-" * 50)
print(f"处理完成!结果保存在: {output_path}")
# 处理文件夹
elif input_path.is_dir():
output_folder = args.output if args.output else 'output'
process_images_folder(
str(input_path),
output_folder,
model_name=args.model,
alpha_matting=args.alpha_matting,
alpha_matting_foreground_threshold=args.foreground_threshold,
alpha_matting_background_threshold=args.background_threshold,
alpha_matting_erode_size=args.erode_size,
post_process_mask=args.post_process
)
else:
print(f"错误: 不支持的输入类型: {args.input}")
exit(1)