63 lines
1.9 KiB
Python
63 lines
1.9 KiB
Python
import cv2
|
||
import numpy as np
|
||
|
||
def simple_background_subtraction(background_path, foreground_path, output_path, threshold=30):
|
||
"""
|
||
使用前后两张图做差分,分离前景
|
||
"""
|
||
bg = cv2.imread(background_path)
|
||
fg_img = cv2.imread(foreground_path)
|
||
|
||
if bg is None or fg_img is None:
|
||
raise FileNotFoundError("图片没找到!检查路径")
|
||
|
||
# 确保两图大小一致
|
||
if bg.shape != fg_img.shape:
|
||
print("⚠️ 图片大小不一致,正在调整...")
|
||
fg_img = cv2.resize(fg_img, (bg.shape[1], bg.shape[0]))
|
||
|
||
# 转灰度 + 差分
|
||
bg_gray = cv2.cvtColor(bg, cv2.COLOR_BGR2GRAY)
|
||
fg_gray = cv2.cvtColor(fg_img, cv2.COLOR_BGR2GRAY)
|
||
diff = cv2.absdiff(fg_gray, bg_gray)
|
||
|
||
# 二值化
|
||
_, mask = cv2.threshold(diff, threshold, 255, cv2.THRESH_BINARY)
|
||
|
||
# 形态学去噪
|
||
kernel = np.ones((5,5), np.uint8)
|
||
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
|
||
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
|
||
|
||
# 提取前景:背景变白
|
||
result_white = fg_img.copy()
|
||
result_white[mask == 0] = [255, 255, 255] # 背景白
|
||
|
||
# 提取前景:背景透明(PNG)
|
||
b, g, r = cv2.split(fg_img)
|
||
alpha = np.where(mask > 0, 255, 0).astype(np.uint8)
|
||
result_transparent = cv2.merge([b, g, r, alpha])
|
||
|
||
# 保存
|
||
cv2.imwrite(output_path + "_white.jpg", result_white)
|
||
cv2.imwrite(output_path + "_transparent.png", result_transparent)
|
||
|
||
print(f"✅ 保存成功:\n {output_path}_white.jpg\n {output_path}_transparent.png")
|
||
|
||
# 显示(可选)
|
||
cv2.imshow('Original', fg_img)
|
||
cv2.imshow('Diff', diff)
|
||
cv2.imshow('Mask', mask)
|
||
cv2.imshow('Foreground', result_white)
|
||
cv2.waitKey(0)
|
||
cv2.destroyAllWindows()
|
||
|
||
|
||
# === 使用 ===
|
||
if __name__ == '__main__':
|
||
simple_background_subtraction(
|
||
background_path='f.jpg',
|
||
foreground_path='b.jpg',
|
||
output_path='output/foreground',
|
||
threshold=30
|
||
) |