一、前言
现在有较多的图片需要处理,需要将每张图片都去除背景。通常,我们使用像Photoshop这样的专业抠图软件或者在线抠图网页来处理,但这些方法通常只能一张一张地手动操作,效率低下。
接下来将介绍使用Python批量处理,一键去除文件夹中所有图片的背景,从而大大提高工作效率。
二、Python环境准备
使用cv2读取图片,rembg去除图片背景
pip install opencv-python
pip install rembg
三、代码分步详解
遍历读取图片
示例文件夹如下图:
import os
import cv2
def bg_remove(source_path):
for filename in os.listdir(source_path): # 遍历文件
file_path = source_path + os.sep + filename # 文件路径
img_obj = cv2.imread(file_path) # 读取图片
print(f"{img_obj}")
if __name__ == "__main__":
source_dir = r'C:\Users\Administrator\Desktop\新建文件夹'
bg_remove(source_dir)
运行结果:
问题1--中文路径读取失败
文件路径包含中文时图片读取失败,那么在读取之前需要先判断文件路径是否包中文
import os
import cv2
def bg_remove(source_path):
for filename in os.listdir(source_path): # 遍历文件
file_path = source_path + os.sep + filename # 文件路径
if not is_include_chinese(file_path): # 文件路径不包含中文则读取
img_obj = cv2.imread(file_path) # 读取图片
print(f"{filename} 读取成功")
else: # 文件路径包含中文
print(f"{filename} 路径包含中文")
def is_include_chinese(path):
"""判断文件路径是否包含中文"""
for i in path:
if '\u4e00' <= i <= '\u9fa5':
return True
return False
if __name__ == "__main__":
source_dir_chinese = r'C:\Users\Administrator\Desktop\新建文件夹'
source_dir = r'C:\Users\Administrator\Desktop\img_dir'
bg_remove(source_dir_chinese)
print("=" * 100)
bg_remove(source_dir)
运行结果:
问题2--不读取非图片文件
源文件夹中除了图片文件,还有其他文件类型,读取时需要排除掉
import imghdr
import os
import cv2
def bg_remove(source_path):
for filename in os.listdir(source_path): # 遍历文件
file_path = source_path + os.sep + filename # 文件路径
if not is_include_chinese(file_path): # 文件路径不包含中文则读取
if is_img(file_path): # 是图片文件则读取
img_obj = cv2.imread(file_path) # 读取图片
print(f"{filename} 读取成功")
else: # 不是图片文件
print(f"{filename} 不是图片")
else: # 文件路径包含中文
print(f"{filename} 路径包含中文")
def is_include_chinese(path):
"""判断文件路径是否包含中文"""
for i in path:
if '\u4e00' <= i <= '\u9fa5':
return True
return False
def is_img(path):
"""判断文件是否为图片"""
img_type = imghdr.what(path)
if img_type:
return img_type
else:
return False
if __name__ == "__main__":
source_dir = r'C:\Users\Administrator\Desktop\img_dir'
bg_remove(source_dir)
运行结果:
去除图片背景并保存
import imghdr
import os
import cv2
import rembg
def bg_remove(source_path, target_path):
for filename in os.listdir(source_path): # 遍历文件
file_path = source_path + os.sep + filename # 文件路径
if not is_include_chinese(file_path): # 文件路径不包含中文则读取
if is_img(file_path): # 是图片文件则读取
img_obj = cv2.imread(file_path) # 读取图片
target = rembg.remove(img_obj) # 去除背景
target_file_path = target_path + os.sep + os.path.splitext(filename)[0] + ".png" # 定义目标文件路径和名称
cv2.imwrite(target_file_path, target) # 保存去除背景后的图片到目标文件夹
else: # 不是图片文件
print(f"{filename} 不是图片")
else: # 文件路径包含中文
print(f"{filename} 路径包含中文")
def is_include_chinese(path):
"""判断文件路径是否包含中文"""
for i in path:
if '\u4e00' <= i <= '\u9fa5':
return True
return False
def is_img(path):
"""判断文件是否为图片"""
img_type = imghdr.what(path)
if img_type:
return img_type
else:
return False
if __name__ == "__main__":
source_dir = r'C:\Users\Administrator\Desktop\img_dir'
target_dir = r'C:\Users\Administrator\Desktop\result_dir'
bg_remove(source_dir, target_dir)
运行结果:
问题3--目标文件夹不存在
从代码运行结果来看,图片背景已经去除了,但并未在桌面上找到目标文件夹(C:\Users\Administrator\Desktop\result_dir)和去除背景后的图片,因为代码中并未创建目标文件夹
import imghdr
import os
import cv2
import rembg
def bg_remove(source_path, target_path):
if not os.path.exists(target_path): # 若目标文件夹不存在则创建
os.makedirs(target_path)
for filename in os.listdir(source_path): # 遍历文件
file_path = source_path + os.sep + filename # 文件路径
if not is_include_chinese(file_path): # 文件路径不包含中文则读取
if is_img(file_path): # 是图片文件则读取
img_obj = cv2.imread(file_path) # 读取图片
target = rembg.remove(img_obj) # 去除背景
target_file_path = target_path + os.sep + os.path.splitext(filename)[0] + ".png" # 定义目标文件路径和名称
cv2.imwrite(target_file_path, target) # 保存去除背景后的图片到目标文件夹
else: # 不是图片文件
print(f"{filename} 不是图片")
else: # 文件路径包含中文
print(f"{filename} 路径包含中文")
def is_include_chinese(path):
"""判断文件路径是否包含中文"""
for i in path:
if '\u4e00' <= i <= '\u9fa5':
return True
return False
def is_img(path):
"""判断文件是否为图片"""
img_type = imghdr.what(path)
if img_type:
return img_type
else:
return False
if __name__ == "__main__":
source_dir = r'C:\Users\Administrator\Desktop\img_dir'
target_dir = r'C:\Users\Administrator\Desktop\result_dir'
bg_remove(source_dir, target_dir)
运行结果:
问题4--打印程序运行时间
为方便后期优化调试,将去除图片背景的时间打印出来
import imghdr
import os
import time
import cv2
import rembg
def bg_remove(source_path, target_path):
if not os.path.exists(target_path): # 若目标文件夹不存在则创建
os.makedirs(target_path)
for filename in os.listdir(source_path): # 遍历文件
file_path = source_path + os.sep + filename # 文件路径
if not is_include_chinese(file_path): # 文件路径不包含中文则读取
if is_img(file_path): # 是图片文件则读取
start_time = time.time() # 开始计时
img_obj = cv2.imread(file_path) # 读取图片
target = rembg.remove(img_obj) # 去除背景
target_file_path = target_path + os.sep + os.path.splitext(filename)[0] + ".png" # 定义目标文件路径和名称
cv2.imwrite(target_file_path, target) # 保存去除背景后的图片到目标文件夹
end_time = time.time() # 再次计时
execution_time = round(end_time - start_time, 3) # 计算耗时
print(f"{filename}去除背景完成,耗时:{execution_time}秒")
else: # 不是图片文件
print(f"{filename} 不是图片")
else: # 文件路径包含中文
print(f"{filename} 路径包含中文")
def is_include_chinese(path):
"""判断文件路径是否包含中文"""
for i in path:
if '\u4e00' <= i <= '\u9fa5':
return True
return False
def is_img(path):
"""判断文件是否为图片"""
img_type = imghdr.what(path)
if img_type:
return img_type
else:
return False
if __name__ == "__main__":
source_dir = r'C:\Users\Administrator\Desktop\img_dir'
target_dir = r'C:\Users\Administrator\Desktop\result_dir'
bg_remove(source_dir, target_dir)
运行结果:
四、结语
1.编写了三个方法,每个方法的功能明确,代码更易于理解和维护
2.对中文路径、非图片路径、目标文件夹不存在等异常情况做了简单处理
3.使用OpenCV(cv2)和rembg库来进行图片处理,简化了背景去除操作