import cv2
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

# 读取图像
image_path = 'jigsaw_mask.png'  # 替换为您的图像路径
image = cv2.imread(image_path)

if image is None:
    raise ValueError("无法读取图像，请检查路径是否正确。")

# 转换为RGB
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# 转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 应用固定阈值进行二值化
_, mask = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)

# 进行形态学操作以连接断裂的线条
# 定义较大的核
kernel = np.ones((1,1), np.uint8)

# 增加膨胀次数以连接断裂
mask = cv2.dilate(mask, kernel, iterations=1)

# 闭运算进一步连接
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=5)

# 再次确保掩膜是二值的
_, mask = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY)

# 创建 Alpha 通道
alpha = cv2.bitwise_not(mask)

# 确保 Alpha 通道只有0和255
alpha = cv2.threshold(alpha, 127, 255, cv2.THRESH_BINARY)[1]

# 创建纯白色背景
white_bg = 255 * np.ones_like(image_rgb, dtype=np.uint8)

# 合并 RGB 图像和 Alpha 通道
final_rgb = cv2.bitwise_and(white_bg, white_bg, mask=cv2.bitwise_not(mask))
image_rgba = cv2.cvtColor(final_rgb, cv2.COLOR_RGB2RGBA)
image_rgba[:, :, 3] = alpha

# 将 OpenCV 的 RGBA 图像转换为 Pillow Image 对象
image_pil = Image.fromarray(image_rgba)

# 转换为 NumPy 数组以进一步处理
data = np.array(image_pil)

# 分离颜色通道
red, green, blue, alpha = data.T

# 定义黑色的阈值范围
black_threshold = 50  # 根据需要调整

# 创建掩膜：黑色区域为True，其余为False
black_areas = (red < black_threshold) & (green < black_threshold) & (blue < black_threshold)

# 设置黑色区域的 Alpha 为0，非黑色区域的 Alpha 为255
data[..., 3][black_areas.T] = 0
data[..., 3][~black_areas.T] = 255

# 将非黑色区域设置为纯白色
data[..., 0:3][~black_areas.T] = [255, 255, 255]

# 创建新的 Image 对象
final_image = Image.fromarray(data)

# 保存结果为 PNG（支持透明度）
output_path = 'mask.png'
final_image.save(output_path)

print(f"已保存带纯白背景和透明部分的图像到 {output_path}")

# 可选：显示图像
plt.figure(figsize=(12,6))
plt.subplot(1,2,1)
plt.title('原图')
plt.imshow(image_rgb)
plt.axis('off')

plt.subplot(1,2,2)
plt.title('带纯白背景和透明部分的图像')
plt.imshow(final_image)
plt.axis('off')

plt.show()
