《博主简介》
小伙伴们好,我是阿旭。
专注于计算机视觉领域,包括目标检测、图像分类、图像分割和目标跟踪等项目开发,提供模型对比实验、答疑辅导等。
《------往期经典推荐------》
二、机器学习实战专栏【链接】,已更新31期,欢迎关注,持续更新中~~
三、深度学习【Pytorch】专栏【链接】
四、【Stable Diffusion绘画系列】专栏【链接】
五、YOLOv8改进专栏【链接】,持续更新中~~
六、YOLO性能对比专栏【链接】,持续更新中~
《------正文------》
引言
两篇文章介绍了如何使用DINOv3进行图像前景分割与一键生成热力图。
《【DINOv3教程1-图像分割】使用DINOv3+逻辑回归器进行图像前景分割【附源码】》
《【DINOv3教程2-热力图】使用DINOv3直接生成图像热力图【附源码与详解】》
本文将介绍如何利用DINOv3预训练视觉模型对输入图像进行特征提取,并结合一个前景分类器来识别图像中的前景区域。
随后,它使用主成分分析(PCA)对前景区域的特征进行降维处理,并将结果可视化为RGB图像。
论文中的示例图如下:
整体流程包括图像预处理、特征提取、前景检测、PCA降维和结果可视化等步骤。
基本流程介绍
- 模型加载与初始化
- 使用
transformers.AutoModel.from_pretrained
加载本地的DINOv3预训练模型。 - 从指定路径加载预先训练好的前景分类器(
fg_classifier_large.pkl
)。【训练方法见教程1】
- 使用
from transformers import AutoModel
# 加载本地预训练模型
model = AutoModel.from_pretrained(
r'D:\7studying\DinoV3_Study\dinov3-main\PreModels\dinov3-vitl16-pretrain-sat493m',
local_files_only=True
)
# print( model)
# 设置保存根目录和训练好的前景逻辑回归模型路径
save_root = '.'
model_path = os.path.join(save_root, "fg_classifier_large.pkl")
# 加载前景分类器模型
with open(model_path, 'rb') as file:
clf = pickle.load(file)
图像加载与预处理
load_image_from_path
: 读取并转换图像为RGB格式。resize_transform
: 调整图像尺寸至适合模型处理的大小(确保是patch size的整数倍),并返回tensor格式的图像及对应的patch网格尺寸。
# 定义图像处理参数
PATCH_SIZE = 16 # patch大小
IMAGE_SIZE = 1024 # 图像尺寸
# ImageNet标准化参数
IMAGENET_MEAN = (0.485, 0.456, 0.406)
IMAGENET_STD = (0.229, 0.224, 0.225)
# 测试图像路径
image_path = "3.png"
def load_image_from_path(image_path):
"""
从图片路径加载图像
参数:
image_path (str): 图像文件的路径
返回:
PIL.Image: RGB格式的图像对象
"""
return Image.open(image_path).convert("RGB")
# 图像resize变换,调整为patch size的整数倍尺寸
def resize_transform(
mask_image: Image, # 输入图像
image_size: int = IMAGE_SIZE, # 目标图像尺寸
patch_size: int = PATCH_SIZE, # patch大小
) -> torch.Tensor:
"""
将图像调整为适合模型处理的尺寸
参数:
mask_image: 输入的PIL图像
image_size: 目标图像尺寸
patch_size: patch大小
返回:
tuple: 调整后的tensor图像和网格尺寸(h_patches, w_patches)
"""
w, h = mask_image.size
print("image_shape:", mask_image.size)
h_patches = int(image_size / patch_size)
w_patches = int((w * image_size) / (h * patch_size))
target_size = (h_patches * patch_size, w_patches * patch_size) # (height, width)
# 大小缩放
resized_image = TF.resize(mask_image, target_size)
tensor_image = TF.to_tensor(resized_image)
# 返回tensor和patch网格尺寸
return tensor_image, (h_patches, w_patches)
# 加载并预处理图像
image = load_image_from_path(image_path)
image_resized, (h_patches, w_patches) = resize_transform(image)
print("图像尺寸:", image_resized.shape)
print(h_patches, w_patches)
# 对图像进行标准化处理
image_resized_norm = TF.normalize(image_resized, mean=IMAGENET_MEAN, std=IMAGENET_STD)
- 特征提取
- 对图像进行ImageNet标准化处理。
- 利用DINOv3模型提取图像特征,获取每个patch的特征向量(去除cls token)。
- 检查并调整特征数量以匹配预期的patch网格尺寸。
# 使用模型提取特征
with torch.inference_mode():
outputs = model(image_resized_norm.unsqueeze(0))
# 获取patch特征(去掉cls token)
patch_features = outputs.last_hidden_state[:, 1:, :]
#h_patches, w_patches: 48 36
print("patch_features:", patch_features.shape) #torch.Size([1, 1732, 384])
#第一个维度[1]:表示批次大小(batchsize),这里为1,因为我们一次只处理一张图像。
#第二个维度[1732]:表示patch tokens的数量。这是将图像分割成多个patches后得到的patch数量,每个patch对应一个特征向量。在你的例子中,图像被分成了1732个patches。
#第三个维度[384]:表示每个patch的特征维度,即每个patch的向量表示长度。
x = patch_features.squeeze().detach().cpu()
# 检查并调整特征数量以匹配网格尺寸
expected_patches = h_patches * w_patches
actual_patches = x.shape[0]
if actual_patches > expected_patches:
# 截取前expected_patches个特征
x = x[:expected_patches, :]
print(f"测试时截取特征: {actual_patches} -> {expected_patches}")
elif actual_patches < expected_patches:
raise ValueError(f"测试时特征数量不足: {actual_patches} < {expected_patches}")
# 调整维度顺序
dim = x.shape[-1]
x = x.view(-1, dim)
- 前景检测
- 使用加载的前景分类器预测每个patch属于前景的概率。
- 对前景概率图应用中值滤波(median filtering)以减少噪声。
- 可视化原始图像和前景分数图。
# 重新计算图像的网格尺寸
h_patches, w_patches = [int(d / PATCH_SIZE) for d in image_resized.shape[1:]]
print("h_patches, w_patches:",h_patches, w_patches)
# 使用分类器预测前景概率
print(clf.predict_proba(x).shape) #(1728, 2)
fg_score = clf.predict_proba(x)[:, 1].reshape(h_patches, w_patches)
# 对前景概率图进行中值滤波
fg_score_mf = torch.from_numpy(signal.medfilt2d(fg_score, kernel_size=5))
PCA降维与可视化
- 选择前景概率大于0.5的patches作为前景区域。
- 使用PCA对前景patches进行3维降维处理。
- 将所有patches的特征投影到PCA空间,并重塑为图像格式。
- 应用sigmoid函数增强颜色鲜艳度,并使用前景分数掩码背景。
- 显示最终的PCA结果图像。
# 选择前景概率大于0.5的patches
foreground_selection = fg_score_mf.view(-1) > 0.5
fg_patches = x[foreground_selection]
# 对前景patches进行PCA降维
pca = PCA(n_components=3, whiten=True)
pca.fit(fg_patches)
# 应用PCA变换并重塑图像
projected_image = torch.from_numpy(pca.transform(x.numpy())).view(h_patches, w_patches, 3)
# 乘以2.0并通过sigmoid函数获得鲜艳的颜色
projected_image = torch.nn.functional.sigmoid(projected_image.mul(2.0)).permute(2, 0, 1)
# 使用前景分数掩码背景
projected_image *= (fg_score_mf.unsqueeze(0) > 0.3)
总结
本文详细介绍了如何使用DINOv3进行图像前景提取与利用PCA技术将其特征RGB可视化,通过这些步骤,从而提供对图像内容的深入理解。
好了,这篇文章就介绍到这里,喜欢的小伙伴感谢给点个赞和关注,更多精彩内容持续更新~~
关于本篇文章大家有任何建议或意见,欢迎在评论区留言交流!