分享用Python做的一个mask深度图+图片快捷抠图工具,这是以前为了给手机弄景深壁纸时做的,给自己做了个很简陋能用的,后来觉得有点方便,又有点bug,所以扔给deepseek改了改
用了tkinter,cv2和numpy

使用方法:

准备好图片文件和mask.png文件,运行,在弹出的用tkinter做的个简陋ui界面上选择主图片和深度图就行了
阈值调得越大越精确,但不是越大越效果好,多试试即可

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import cv2
import numpy as np
import os
import tkinter as tk
from tkinter import filedialog, messagebox

class ImageProcessorApp:
def __init__(self, root):
self.root = root
self.root.title("mask抠图")
self.root.geometry("300x400")

title_label = tk.Label(root, text="用image和mask来抠图", font=("微软雅黑", 14))
title_label.pack(pady=10)

self.select_image_button = tk.Button(root, text="选择主图像", command=self.select_image)
self.select_image_button.pack(pady=10)

self.select_mask_button = tk.Button(root, text="选择深度图", command=self.select_mask)
self.select_mask_button.pack(pady=10)

self.process_button = tk.Button(root, text="处理图像", command=self.process_images)
self.process_button.pack(pady=10)

self.image_label = tk.Label(root, text="未选择主图像")
self.image_label.pack(pady=5)

self.mask_label = tk.Label(root, text="未选择深度图")
self.mask_label.pack(pady=0)

self.result_label = tk.Label(root, text="")
self.result_label.pack(pady=0)

self.threshold_label = tk.Label(root, text="调整阈值:", font=("微软雅黑", 10))
self.threshold_label.pack(pady=0)

self.threshold_scale = tk.Scale(root, from_=0, to=255, orient=tk.HORIZONTAL)
self.threshold_scale.set(199)
self.threshold_scale.pack(pady=0)

footer_label = tk.Label(root, text="Make by SkyShadowHeo with python\n(With MIAI,to put it accurately)", font=("微软雅黑", 8))
footer_label.pack(side=tk.BOTTOM, pady=0)

self.image_path = None
self.mask_path = None

def select_image(self):
self.image_path = filedialog.askopenfilename(title="选择主图像",
filetypes=[("图像文件", "*.jpg;*.jpeg;*.png")])
if self.image_path:
self.image_label.config(text=f"已选择主图像: {os.path.basename(self.image_path)}")

def select_mask(self):
self.mask_path = filedialog.askopenfilename(title="选择深度图",
filetypes=[("图像文件", "*.jpg;*.jpeg;*.png")])
if self.mask_path:
self.mask_label.config(text=f"已选择深度图: {os.path.basename(self.mask_path)}")

def process_images(self):
if not self.image_path or not self.mask_path:
messagebox.showerror("错误", "请确保已选择主图像和深度图。")
return

image = cv2.imread(self.image_path)
depth_map = cv2.imread(self.mask_path, cv2.IMREAD_GRAYSCALE)

if image.shape[:2] != depth_map.shape[:2]:
depth_map = cv2.resize(depth_map, (image.shape[1], image.shape[0]), interpolation=cv2.INTER_CUBIC)

normalized_depth = cv2.normalize(depth_map, None, 0, 255, cv2.NORM_MINMAX)

threshold_value = self.threshold_scale.get()
_, mask = cv2.threshold(normalized_depth, threshold_value, 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 = cv2.cvtColor(image, cv2.COLOR_BGR2BGRA)
result[:, :, 3] = mask

output_path = os.path.join(os.getcwd(), f'output_{threshold_value}.png')
cv2.imwrite(output_path, result)

self.result_label.config(text=f"处理结果已保存:\n {output_path}")

if __name__ == "__main__":
root = tk.Tk()
app = ImageProcessorApp(root)
root.mainloop()