plutosss commited on
Commit
2067673
·
verified ·
1 Parent(s): 71bfff1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -135
app.py CHANGED
@@ -1,61 +1,20 @@
1
  from PIL import Image
2
  import cv2
3
  import numpy as np
4
- import os
5
  import torch
6
  import torch.nn.functional as F
7
  from torchvision.transforms import Compose
8
- from tqdm import tqdm
9
- import TEED.main as teed
10
- from TEED.main import parse_args
11
 
12
  from depthAnything.depth_anything.dpt import DepthAnything
13
  from depthAnything.depth_anything.util.transform import Resize, NormalizeImage, PrepareForNet
14
- import shutil
15
-
16
- def multiply_blend(image1, image2):
17
- # 确保 image2 具有与 image1 相同的形状
18
- image2 = np.stack((image2,) * 3, axis=-1)
19
- # 执行混合操作
20
- multiplied = np.multiply(image1 / 255.0, image2 / 255.0) * 255.0
21
- return multiplied.astype(np.uint8)
22
-
23
- def screen_blend(image1, image2):
24
- image1 = image1.astype(float)
25
- image2 = image2.astype(float)
26
- screened = 1 - (1 - image1 / 255) * (1 - image2 / 255) * 255
27
- result = np.clip(screened, 0, 255).astype('uint8')
28
- return result
29
-
30
- def erosion(img, kernel_size=3, iterations=1, dilate=False):
31
- if len(img.shape) == 3:
32
- img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
33
- kernel = np.ones((kernel_size, kernel_size), np.uint8)
34
- if dilate:
35
- img = cv2.dilate(img, kernel, iterations=iterations)
36
- else:
37
- img = cv2.erode(img, kernel, iterations=iterations)
38
- return img
39
-
40
- def teed_imgs(img_path='./input', outdir='./output/teed_imgs', gaussianBlur=[0, 3, 0]):
41
- os.makedirs(outdir, exist_ok=True)
42
- os.makedirs('teed_tmp', exist_ok=True)
43
-
44
- if os.path.isfile(img_path):
45
- img = cv2.imread(img_path)
46
- if gaussianBlur[0] != 0:
47
- img = cv2.GaussianBlur(img, (gaussianBlur[1], gaussianBlur[1]), gaussianBlur[2])
48
- cv2.imwrite(os.path.join('teed_tmp', 'temp_image.png'), img)
49
- else:
50
- cv2.imwrite(os.path.join('teed_tmp', 'temp_image.png'), img)
51
 
52
- args, train_info = parse_args(is_testing=True, pl_opt_dir=outdir)
53
- args.input_val_dir = 'teed_tmp'
54
- teed.main(args, train_info)
55
-
56
- shutil.rmtree('teed_tmp')
57
 
58
- def depth_anything(img_path='./input', outdir='./output/depth_anything', encoder='vitl', pred_only=True, grayscale=True):
 
59
  DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'
60
 
61
  model_configs = {
@@ -65,98 +24,92 @@ def depth_anything(img_path='./input', outdir='./output/depth_anything', encoder
65
  }
66
 
67
  depth_anything = DepthAnything(model_configs[encoder])
68
- depth_anything.load_state_dict(torch.load('./checkpoints/depth_anything_{}14.pth'.format(encoder)))
69
  depth_anything = depth_anything.to(DEVICE).eval()
70
 
71
  transform = Compose([
72
- Resize(width=518, height=518, resize_target=False, keep_aspect_ratio=True, ensure_multiple_of=14, resize_method='lower_bound', image_interpolation_method=cv2.INTER_CUBIC),
 
73
  NormalizeImage(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
74
  PrepareForNet(),
75
  ])
76
 
77
- if os.path.isfile(img_path):
78
- raw_image = cv2.imread(img_path)
79
- image = cv2.cvtColor(raw_image, cv2.COLOR_BGR2RGB) / 255.0
80
- h, w = image.shape[:2]
81
- image = transform({'image': image})['image']
82
- image = torch.from_numpy(image).unsqueeze(0).to(DEVICE)
83
-
84
- with torch.no_grad():
85
- depth = depth_anything(image)
86
-
87
- depth = F.interpolate(depth[None], (h, w), mode='bilinear', align_corners=False)[0, 0]
88
- depth = (depth - depth.min()) / (depth.max() - depth.min()) * 255.0
89
- depth = depth.cpu().numpy().astype(np.uint8)
90
-
91
- if grayscale:
92
- depth = np.repeat(depth[..., np.newaxis], 3, axis=-1)
93
- else:
94
- depth = cv2.applyColorMap(depth, cv2.COLORMAP_INFERNO)
95
-
96
- filename = os.path.basename(img_path)
97
- cv2.imwrite(os.path.join(outdir, filename[:filename.rfind('.')] + '_depth.png'), depth)
98
-
99
- def process_line(img_path='./input', outdir='./output'):
100
- depth_anything(img_path, os.path.join(outdir, "depth_anything"))
101
- teed_imgs(img_path, os.path.join(outdir, "teed_imgs"), [1, 7, 2])
102
- teed_imgs(os.path.join(outdir, "depth_anything"), os.path.join(outdir, "dp_teed_imgs"), [0, 7, 2])
103
-
104
- merge_images_in_2_folder(
105
- os.path.join(outdir, "teed_imgs"),
106
- os.path.join(outdir, "dp_teed_imgs"),
107
- os.path.join(outdir, "merged_imgs"),
108
- '_depth',
109
- 1,
110
- 'multiply',
111
- [[2, 0], [2, 1]],
112
- [1, 0]
113
- )
114
-
115
- def merge_2_images(img1, img2, mode, erosion_para=[[0, 0], [0, 0]], dilate=[0, 0]):
116
- img1 = cv2.imread(img1)
117
- img2 = cv2.imread(img2)
118
- img1 = cv2.resize(img1, (img2.shape[1], img2.shape[0]))
119
- if erosion_para[0][1] != 0:
120
- img1 = erosion(img1, erosion_para[0][0], erosion_para[0][1], dilate[0])
121
- if erosion_para[1][1] != 0:
122
- img2 = erosion(img2, erosion_para[1][0], erosion_para[1][1], dilate[1])
123
- if mode == 'multiply':
124
- return multiply_blend(img1, img2)
125
- elif mode == 'screen':
126
- return screen_blend(img1, img2)
127
-
128
- def merge_images_in_2_folder(folder1, folder2, outdir, suffix_need_remove=None, suffix_floder=0, mode='multiply', erosion_para=[[0, 0], [0, 0]], dilate=[0, 0]):
129
- os.makedirs(outdir, exist_ok=True)
130
- name_extension_pairs_folder1 = [os.path.splitext(filename) for filename in os.listdir(folder1) if filename.endswith(('.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.webp', 'tif'))]
131
- filenames_noext_folder1, extensions_folder1 = zip(*name_extension_pairs_folder1)
132
- name_extension_pairs_folder2 = [os.path.splitext(filename) for filename in os.listdir(folder2) if filename.endswith(('.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.webp', 'tif'))]
133
- filenames_noext_folder2, extensions_folder2 = zip(*name_extension_pairs_folder2)
134
-
135
- for index, filename in enumerate(filenames_noext_folder1):
136
- if filename in filenames_noext_folder2:
137
- img1 = os.path.join(folder1, filename + extensions_folder1[index])
138
- img2 = os.path.join(folder2, filename + extensions_folder2[filenames_noext_folder2.index(filename)])
139
- result = merge_2_images(img1, img2, mode, erosion_para, dilate)
140
- cv2.imwrite(os.path.join(outdir, filename + extensions_folder1[index]), result)
141
-
142
- if __name__ == '__main__':
143
- import gradio as gr
144
-
145
- def gradio_process_line(img):
146
- img_path = './temp_input.png'
147
- img.save(img_path)
148
-
149
- process_line(img_path, './output')
150
-
151
- output_image_path = './output/merged_imgs/temp_input.png' # 更新为实际输出路径
152
- return Image.open(output_image_path)
153
-
154
- iface = gr.Interface(
155
- fn=gradio_process_line,
156
- inputs=gr.Image(type="pil"),
157
- outputs=gr.Image(type="pil"),
158
- title="Image Processing with Depth Anything and TEED",
159
- description="Upload an image to process it with depth estimation and edge detection."
160
- )
161
-
162
- iface.launch()
 
1
  from PIL import Image
2
  import cv2
3
  import numpy as np
 
4
  import torch
5
  import torch.nn.functional as F
6
  from torchvision.transforms import Compose
7
+ import shutil
8
+ import os
 
9
 
10
  from depthAnything.depth_anything.dpt import DepthAnything
11
  from depthAnything.depth_anything.util.transform import Resize, NormalizeImage, PrepareForNet
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
+ # 保留原有图像处理函数如multiply_blend、screen_blend、erosion等
14
+ # 这些函数无需修改
 
 
 
15
 
16
+ # 修改depth_anything函数,直接处理传入的图片
17
+ def depth_anything_image(image, encoder='vitl', pred_only=True, grayscale=True):
18
  DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'
19
 
20
  model_configs = {
 
24
  }
25
 
26
  depth_anything = DepthAnything(model_configs[encoder])
27
+ depth_anything.load_state_dict(torch.load(f'./checkpoints/depth_anything_{encoder}14.pth'))
28
  depth_anything = depth_anything.to(DEVICE).eval()
29
 
30
  transform = Compose([
31
+ Resize(width=518, height=518, resize_target=False, keep_aspect_ratio=True,
32
+ ensure_multiple_of=14, resize_method='lower_bound', image_interpolation_method=cv2.INTER_CUBIC),
33
  NormalizeImage(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
34
  PrepareForNet(),
35
  ])
36
 
37
+ raw_image = np.array(image.convert('RGB'))
38
+ raw_image = raw_image[:, :, ::-1].copy() # Convert RGB to BGR for OpenCV
39
+
40
+ h, w = raw_image.shape[:2]
41
+
42
+ image_tensor = transform({'image': raw_image / 255.0})['image']
43
+ image_tensor = torch.from_numpy(image_tensor).unsqueeze(0).to(DEVICE)
44
+
45
+ with torch.no_grad():
46
+ depth = depth_anything(image_tensor)
47
+
48
+ depth = F.interpolate(depth[None], (h, w), mode='bilinear', align_corners=False)[0, 0]
49
+ depth = (depth - depth.min()) / (depth.max() - depth.min()) * 255.0
50
+ depth = depth.cpu().numpy().astype(np.uint8)
51
+
52
+ if grayscale:
53
+ depth = np.repeat(depth[..., np.newaxis], 3, axis=-1)
54
+ else:
55
+ depth = cv2.applyColorMap(depth, cv2.COLORMAP_INFERNO)
56
+
57
+ if pred_only:
58
+ return depth
59
+ else:
60
+ combined_results = np.hstack([raw_image, depth])
61
+ return combined_results
62
+
63
+ # TEED function modified to process a single image
64
+ def teed_process_image(image, gaussianBlur=[0, 3, 0]):
65
+ temp_image_path = './teed_temp_image.png'
66
+ os.makedirs('teed_tmp', exist_ok=True)
67
+
68
+ img = np.array(image.convert('RGB'))[:, :, ::-1].copy() # Convert RGB to BGR for OpenCV
69
+
70
+ if gaussianBlur[0] != 0:
71
+ img = cv2.GaussianBlur(img, (gaussianBlur[1], gaussianBlur[1]), gaussianBlur[2])
72
+
73
+ cv2.imwrite(temp_image_path, img)
74
+
75
+ # Run TEED on the image
76
+ args, train_info = parse_args(is_testing=True, pl_opt_dir='./output/teed_imgs')
77
+ args.input_val_dir = 'teed_tmp' # Temporary directory for single image processing
78
+ teed.main(args, train_info)
79
+
80
+ processed_image = cv2.imread(temp_image_path) # Load the processed image
81
+ shutil.rmtree('teed_tmp') # Clean up the temporary directory
82
+
83
+ return processed_image
84
+
85
+ # 修改处理流程,处理单个上传的图片
86
+ def process_single_image(image):
87
+ # 深度处理
88
+ depth_result = depth_anything_image(image, 'vitl')
89
+
90
+ # TEED 边缘检测
91
+ teed_result = teed_process_image(image)
92
+
93
+ # 将两个结果叠加合并(例如 Multiply)
94
+ merged_result = multiply_blend(depth_result, teed_result)
95
+
96
+ return merged_result
97
+
98
+ # Gradio界面处理函数
99
+ def gradio_process_line(img):
100
+ processed_image = process_single_image(img)
101
+ return Image.fromarray(processed_image[:, :, ::-1]) # Convert BGR back to RGB for PIL
102
+
103
+ # Gradio 界面
104
+ import gradio as gr
105
+
106
+ iface = gr.Interface(
107
+ fn=gradio_process_line,
108
+ inputs=gr.Image(type="pil"),
109
+ outputs=gr.Image(type="pil"),
110
+ title="Image Processing with Depth Anything and TEED",
111
+ description="Upload an image to process it with depth estimation and edge detection."
112
+ )
113
+
114
+ # 启动 Gradio 应用
115
+ iface.launch()