如何进行 interpolate_depth , 如何对深度进行插值

本文解析了D2net中interpolate_depth函数,通过实例说明如何从高分辨率深度图中为低分辨率特征图插值深度值,解释了坐标筛选、深度检查和返回结果的重要性。涉及的关键概念包括坐标合法性、下采样深度匹配和索引操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果乍一看,比较奇怪的就是 D2net的 interpolate_depth的代码了,这里就进行我的粗浅的理解分析。

首先是这部分代码:
在这里插入图片描述
如果我用一句话概括,就这这里进行了简单的坐标是否合法的筛选, 因为按照前面教程,咱们输入的 pos 是一个小数的坐标。 这里得到的 valid_corners 其实就是 判断 例如 (3.5 7.5 )这个坐标的左上,左下,右上,右下是不是合法的坐标。 3.5 7.5 的四个角那肯定是没问题的啊。 但是你说 0,0 这个位置,他的左上角就是不存在的,所以说需要筛选一下,就是这回事。
这里得到的 valid_corners 就是一个 True False 的Mask。 指示每个坐标是不是合法的。


紧接着呢, 是把所有合法的四个角,分成四份 取出来。 如下所示。
然后直接index 在深度图上,看看深度图的这些角处,是不是合法的深度。从而再次生成一个 depth_mask。 代表depth中每个点是不是合法的。
在这里插入图片描述
直接看最终的结果,你只用记住下面的东西:
假如输入的 pos 是60 x 80 的, 而 最原始的depth是 480x640 的。
理论上来说,很难得到 下采样 1/8 的特征图,每个点的真实深度值对吧。因为这里的特征图,是60x80的根本和原始的深度值 480x640对不上号啊对吧。 但是,我们就是要通过 480x640的深度图插值出, 特征图每个点对应的4800个深度!!!注意这4800个点,可不是每个点都有深度的,可能有深度的只有 4700个点
知道了上面的东西后, 接着看代码的三个返回结果。 分别是:

interpolated_depth:  这 (可能比4800少,假设4700个)个点中,每个点的深度值
pos:   这4700个点的坐标
ids: 这4700个点每个点 在原来 4800数组中的索引(一维索引)

在这里插入图片描述

# -*- coding: gbk -*- import cv2 import torch import numpy as np import os def enhance_depth_estimation(img_path, mask_path): # 加载模型 midas = torch.hub.load("/home/lichuang/project/Opencv-main/sam_yolo/MiDaS/", "DPT_Large", source='local') device = torch.device("cuda" if torch.cuda.is_available() else "cpu") midas.to(device) midas.eval() # 预处理 img = cv2.imread(img_path) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) / 255.0 mask = cv2.imread(mask_path, cv2.IMREAD_GRAYSCALE) # 确保 mask 中的值为 0 和 1,白色部分为 1 mask = (mask > 0).astype(np.uint8) # 应用 mask img_masked = cv2.bitwise_and(img, img, mask=mask) # 转换为模型输入格式,使用图像原始尺寸 input_batch = torch.from_numpy(img_masked).permute(2, 0, 1).unsqueeze(0).float().to(device) # 不再进行插值到 (384, 384) # 深度预测 with torch.no_grad(): prediction = midas(input_batch) prediction = torch.nn.functional.interpolate( prediction.unsqueeze(1), size=img.shape[:2], # 使用图像原始尺寸 mode="bicubic", align_corners=False ).squeeze().cpu().numpy() # 边缘修复 depth_map = (prediction - prediction.min()) / (prediction.max() - prediction.min()) inpainted_depth = cv2.inpaint((depth_map * 255).astype(np.uint8), 255 - mask, 3, cv2.INPAINT_TELEA) return inpainted_depth def process_folders(segmented_folder, mask_folder, output_folder): # 确保输出文件夹存在 os.makedirs(output_folder, exist_ok=True) # 递归遍历分割图文件夹 for root, _, files in os.walk(segmented_folder): for filename in files: if filename.endswith(('.png', '.jpg', '.jpeg')): img_path = os.path.join(root, filename) # 计算相对路径 relative_path = os.path.relpath(root, segmented_folder) mask_path = os.path.join(mask_folder, relative_path, filename) # 检查对应的掩码文件是否存在 if not os.path.exists(mask_path): print(f"未找到对应的掩码文件: {mask_path},跳过 {img_path}。") continue # 生成深度图 depth_map = enhance_depth_estimation(img_path, mask_path) # 构建输出路径,保持子文件夹结构 output_subfolder = os.path.join(output_folder, relative_path) os.makedirs(output_subfolder, exist_ok=True) output_path = os.path.join(output_subfolder, filename) # 保存深度图 cv2.imwrite(output_path, depth_map) print(f"已为 {img_path} 生成深度图并保存到 {output_path}。") if __name__ == "__main__": segmented_folder = "/home/lichuang/project/Opencv-main/sam_yolo/dataset/input_images/" # 替换为实际的分割图文件夹路径 mask_folder = "/home/lichuang/project/Opencv-main/sam_yolo/dataset/masks/" # 替换为实际的掩码文件夹路径 output_folder = "/home/lichuang/project/Opencv-main/sam_yolo/dataset/depth_maps1/" # 替换为实际的输出深度图文件夹路径 process_folders(segmented_folder, mask_folder, output_folder)修改深度图的生成代码,尝试解决此问题
03-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值