| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- """
- 使用 rembg 库进行图像背景移除
- """
- import sys
- import os
- from rembg import remove
- from PIL import Image
- from glob import glob
- SUPPORTED_FORMATS = ['.jpg', '.jpeg', '.png', '.bmp', '.webp', '.tiff', '.tif']
- def extract_character_rembg(input_path, output_path):
- """
- 使用 rembg 库移除图像背景
- """
- try:
- print(f' -> 读取图片: {os.path.basename(input_path)}')
-
- if not os.path.exists(input_path):
- print(f' [X] 错误: 文件不存在')
- return False
-
- # 创建输出目录
- output_dir = os.path.dirname(output_path)
- if output_dir and not os.path.exists(output_dir):
- print(f' -> 创建输出目录: {output_dir}')
- os.makedirs(output_dir, exist_ok=True)
-
- # 读取输入图像
- print(f' -> 加载图像...')
- input_image = Image.open(input_path)
- original_size = input_image.size
- print(f' 图像尺寸: {original_size[0]}x{original_size[1]}')
-
- # 确保输入图像是RGB模式
- if input_image.mode != 'RGB':
- print(f' -> 转换颜色模式: {input_image.mode} -> RGB')
- input_image = input_image.convert('RGB')
-
- # 使用 rembg 移除背景
- print(f' -> 执行AI抠图...')
- output_image = remove(input_image, post_process_mask=False)
- print(f' [OK] 抠图完成')
-
- # 确保输出图像尺寸与输入图像一致
- if output_image.size != original_size:
- print(f' -> 调整图像尺寸')
- final_image = Image.new('RGBA', original_size, (0, 0, 0, 0))
- final_image.paste(output_image, (0, 0), output_image if output_image.mode == 'RGBA' else None)
- output_image = final_image
- else:
- if output_image.mode != 'RGBA':
- output_image = output_image.convert('RGBA')
-
- # 保存结果
- print(f' -> 保存结果: {os.path.basename(output_path)}')
- output_image.save(output_path, 'PNG')
- print(f' [OK] 保存成功')
- return True
-
- except Exception as error:
- print(f' [X] 处理失败: {error}')
- return False
- def process_folder(input_folder, output_folder):
- """
- 批量处理文件夹中的所有图片
- """
- print('=' * 60)
- print('[Step 1/2] AI Image Matting')
- print('=' * 60)
-
- if not os.path.exists(input_folder):
- print(f'[X] Error: Input folder not found: {input_folder}')
- return 0
-
- print(f'-> Input folder: {input_folder}')
-
- # 创建输出文件夹
- if not os.path.exists(output_folder):
- print(f'-> Creating output folder: {output_folder}')
- os.makedirs(output_folder, exist_ok=True)
- else:
- print(f'-> Output folder: {output_folder}')
-
- # 获取所有支持的图片文件
- print(f'-> Scanning image files...')
- image_files = []
- for ext in SUPPORTED_FORMATS:
- image_files.extend(glob(os.path.join(input_folder, f'*{ext}')))
- image_files.extend(glob(os.path.join(input_folder, f'*{ext.upper()}')))
-
- # 去重(Windows文件系统不区分大小写,可能重复)
- image_files = list(set(image_files))
- image_files.sort()
-
- if not image_files:
- print(f'[X] No supported image files found')
- return 0
-
- print(f'[OK] Found {len(image_files)} images')
- print('-' * 60)
-
- success_count = 0
- for idx, input_path in enumerate(image_files, 1):
- filename = os.path.basename(input_path)
- name_without_ext = os.path.splitext(filename)[0]
- output_path = os.path.join(output_folder, f'{name_without_ext}.png')
-
- print(f'\n[{idx}/{len(image_files)}] {filename}')
- print(f'PROGRESS: {idx}/{len(image_files)}')
-
- if extract_character_rembg(input_path, output_path):
- success_count += 1
- print(f' [OK] Done')
-
- print('\n' + '=' * 60)
- print(f'[Step 1 Complete] Success: {success_count}/{len(image_files)}')
- print('=' * 60)
- return success_count
- if __name__ == '__main__':
- if len(sys.argv) != 3:
- print('用法: python image-matting.py <输入文件夹> <输出文件夹>')
- sys.exit(1)
-
- input_folder = sys.argv[1]
- output_folder = sys.argv[2]
-
- processed = process_folder(input_folder, output_folder)
- sys.exit(0 if processed > 0 else 1)
|