Spaces:
Runtime error
Runtime error
Update app.py
Browse files
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 |
-
|
| 9 |
-
import
|
| 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 |
-
|
| 53 |
-
|
| 54 |
-
teed.main(args, train_info)
|
| 55 |
-
|
| 56 |
-
shutil.rmtree('teed_tmp')
|
| 57 |
|
| 58 |
-
|
|
|
|
| 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'
|
| 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,
|
|
|
|
| 73 |
NormalizeImage(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
|
| 74 |
PrepareForNet(),
|
| 75 |
])
|
| 76 |
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
[
|
| 112 |
-
|
| 113 |
-
)
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 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()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|