93 lines
2.4 KiB
Python
93 lines
2.4 KiB
Python
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()
|