上下文视觉提示实现zero-shot分割检测及多visual-prompt改造
文章目录
- 一、Closed-Set VS Open-set
- 二、DINOv
- 2.1 论文和代码
- 2.2 内容
- 2.3 安装部署
- 2.4 使用效果
- 三、多visual prompt 改造
- 3.1 获取示例图mask
- 3.2 修改函数参数
- 3.3 推理代码
- 3.4 效果的提升!
- 四、总结
本文主要介绍visual prompt模型DINOv,该模型可输入八张目标示例图作为参考,告诉模型我要找的目标长这样,在新的图片上进行推理,实现实例分割的效果。
但一些复杂的场景,八张的示例图不能让模型完全的学习到目标的特征,因此扩展模型能力,让visual prompt数量不受限制,对实际场景应用是非常有必要的(附改造方法、改造代码)。
一、Closed-Set VS Open-set
Closed-Set模型只需要关注有限数量的已知类别,答案选项是预先定义的,这意味着模型的输出范围是有限的、固定的,并且只限于训练时已知的选项,例如YOLO;Open-Set模型可以识别不属于任何已知类别的样本,即其输出范围不是固定的,具备一定的泛化能力和鲁棒性,以应对这些未知的挑战,例如SAM。
在某些特定的应用场景中,仅仅依赖文本提示(text prompt)来描述目标对象,对于Open-Set大模型来说,可能并不足以实现精准识别。若能够额外提供示例图像(visual prompt),将有助于模型更准确地理解我们的意图,从而提升整体的识别效果。
下图是DINOv作者提供的demo界面,左上角输入油污推理图,左下角输入多张油污示例图,并用画笔进行mask,运行模型可得到右边的推理效果。

二、DINOv
2.1 论文和代码
论文名称:《Visual In-Context Prompting》
code:https://github.com/UX-Decoder/DINOv
demo:http://semantic-sam.xyzou.net:6099/
2.2 内容
上下文提示是一种利用少量示例任务来指导模型完成新任务的技术。在视觉任务中,这种技术可以通过提供一组带有标签的图像作为示例,来引导模型理解和解决新的视觉任务。
模型通过学习少量的带有标签的样本图像,提取出这些图像中的关键特征和模式,然后利用这些特征和模式来生成针对新图像的查询。这个查询可以引导模型在新图像中定位并分割出目标物体。具体来说,模型可能通过学习示例图像中的物体形状、颜色、纹理等特征,以及这些特征与标签之间的关系,来构造出查询。然后,模型将这个查询应用于其他图像,通过匹配和比较查询与图像中的特征,来定位并分割出目标物体。最终,模型会生成一个掩码,标记出分割出的物体区域。
以图片作为提示(visual prompt),在提示图上通过笔画、画mask等方法作为视觉prompt,可推理出侧视图中同类目标,达到zero-shot目标分割的效果。
说明:在降落伞进行mask标注,在新的降落伞场景可分割出降落伞,其他场景同理
2.3 安装部署
系统要求:gcc版本>=4.9
# 1、离线安装detectron2
# 下载https://github.com/MaureenZOU/detectron2-xyz.git
Unzip detectron2-xyz.zip # 解压
Cd detectron2-xyz
Pip install -e .
# 2、离线安装panopticapi
# 下载https://github.com/cocodataset/panopticapi.git
Unzip panopticapi.zip # 解压
Cd panopticapi
Pip install -e .
# 3、启动DINOv
# 下载DINOv,https://github.com/UX-Decoder/DINOv
Unzip DINOv.zip # 解压
cd DINOv
python -m pip install -r requirements.txt
python demo_openset.py --ckpt /path/to/swinL/ckpt
# 终端返回下图链接
注:在浏览器访问public URL,建议使用梯子,local URL直接用即可
2.4 使用效果
通过界面输入八张示例图,在一些大目标、规整目标(如矩形、圆形),效果较好,在复杂场景、小目标、不规则物体,无法达到预期效果,例如墙缝缺陷,无法分割裂缝。
三、多visual prompt 改造
使用八张图片作为示例图,可能无法完全学习到目标。在实际使用中,我们可能采集到一小部分图片,例如50张、100张等;如何让DINOv不受限制,可支持多张输入呢?
3.1 获取示例图mask
使用labelme标注工具,生成json标注文件,使用下面代码将json转化为标注mask图。

import json
import cv2
import os
import matplotlib.pyplot as plt
import numpy as npdef generate_mask(img_path, json_path, save_path):img = cv2.imread(img_path)img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)mask = np.zeros_like(img)with open(json_path, "r") as f:tmp = f.read()tmp = json.loads(tmp)tmp_shapes = tmp["shapes"]for shape in tmp_shapes:points = shape["points"]points = np.array(points, np.int32)cv2.fillPoly(mask, [points], (255, 255, 255)) img_add = cv2.addWeighted(mask, 0.3,img,0.7,0)cv2.imwrite(save_path, mask)if __name__ == "__main__":imgs_dir = "./imgs" # 图片目录jsons_dir = "./jsons" # 标注的json文件存放目录save_dir = "./masks" # 生成mask图保存目录img_files = os.listdir(imgs_dir)for img_name in img_files:img_path = os.path.join(imgs_dir, img_name)json_path = os.path.join(jsons_dir, img_name.split('.')[0]+'.json')if os.path.exists(json_path):save_path = os.path.join(save_dir, img_name)generate_mask(img_path, json_path, save_path)
3.2 修改函数参数
修改文件路径:demo/openset_task.py
作用:将原8张图输入修改为列表不限制输入
# 原代码31-37行
def task_openset(model,generic_vp1, generic_vp2, generic_vp3, generic_vp4,generic_vp5, generic_vp6, generic_vp7, generic_vp8, image_tgt=None, text_size=640,hole_scale=100,island_scale=100):in_context_examples = [generic_vp1, generic_vp2, generic_vp3, generic_vp4,generic_vp5, generic_vp6, generic_vp7, generic_vp8]in_context_examples = [x for x in in_context_examples if x is not None]t = []t.append(transforms.Resize(int(text_size), interpolation=Image.BICUBIC))
# 替换代码
def task_openset(model,refer_img_list, image_tgt=None, text_size=640,hole_scale=100,island_scale=100):# in_context_examples = [generic_vp1, generic_vp2, generic_vp3, generic_vp4,# generic_vp5, generic_vp6, generic_vp7, generic_vp8]in_context_examples = refer_img_listin_context_examples = [x for x in in_context_examples if x is not None]t = []t.append(transforms.Resize(int(text_size), interpolation=Image.BICUBIC))
3.3 推理代码
自定义imgs_dir、mask_dir、tgt_dir,执行代码,可在save_dir中找到结果图
import torch
import argparse
from PIL import Image
import cv2
import osfrom dinov.BaseModel import BaseModel
from dinov import build_model
from utils.arguments import load_opt_from_config_filefrom demo.openset_task import task_openset def parse_option():parser = argparse.ArgumentParser('DINOv Demo', add_help=False)parser.add_argument('--conf_files', default="configs/dinov_sam_coco_swinl_train.yaml", metavar="FILE", help='path to config file', )parser.add_argument('--ckpt', default="model_swinL.pth", metavar="FILE", help='path to ckpt')parser.add_argument('--port', default=6099, type=int, help='path to ckpt', )args = parser.parse_args()return args'''
build args
'''
args = parse_option()'''
build model
'''sam_cfg=args.conf_filesopt = load_opt_from_config_file(sam_cfg)model_sam = BaseModel(opt, build_model(opt)).from_pretrained(args.ckpt).eval().cuda()@torch.no_grad()
def inference(refer_img_list, image2,*args, **kwargs):with torch.autocast(device_type='cuda', dtype=torch.float16):model=model_sama= task_openset(model, refer_img_list, image2, *args, **kwargs)return a"""
读取image和labelme标注的mask图
推理一整个目录的图片
"""def inference_dir(imgs_dir, mask_dir, tgt_dir, save_dir):files = os.listdir(tgt_dir)result_img_list = []for file in files:print(f'==={file}==')image_tgt_path = os.path.join(tgt_dir, file)image_tgt = Image.open(image_tgt_path).convert('RGB')refer_img_list = []img_files = os.listdir(imgs_dir)for img_name in img_files:img_path = os.path.join(imgs_dir, img_name)mask_path = os.path.join(mask_dir, img_name)if os.path.exists(mask_path):generic_vp= {"image":"", "mask":""}generic_vp["image"] = Image.open(img_path).convert('RGB')generic_vp["mask"] = Image.open(mask_path).convert('RGB')refer_img_list.append(generic_vp)# print(len(refer_img_list))res = inference(refer_img_list, image_tgt)res = cv2.cvtColor(res, cv2.COLOR_RGB2BGR)cv2.imwrite(os.path.join(save_dir, os.path.basename(image_tgt_path)), res)if __name__ == "__main__":imgs_dir = "./test_img_2/group_50/refer/imgs" # 示例图目录mask_dir = "./test_img_2/group_50/refer/masks" # 示例mask图目录tgt_dir = "./test_img_2/tgt" # 推理图目录save_dir = "results/group_50/" # 结果保存目录inference_dir(imgs_dir, mask_dir, tgt_dir, save_dir)
3.4 效果的提升!
在验证多visual prompt对结果的影响,采用了对比实验。在光学镜头缺陷场景中,8张visual prompt和50张visual prompt进行对比,50张visual prompt得到的推理效果更优!
四、总结
如果文章对您有所帮助,记得点赞、收藏、评论探讨✌️
相关文章:

上下文视觉提示实现zero-shot分割检测及多visual-prompt改造
文章目录 一、Closed-Set VS Open-set二、DINOv2.1 论文和代码2.2 内容2.3 安装部署2.4 使用效果 三、多visual prompt 改造3.1 获取示例图mask3.2 修改函数参数3.3 推理代码3.4 效果的提升! 四、总结 本文主要介绍visual prompt模型DINOv,该模型可输入八…...

WebGL学习(一)渲染关系
学习webgl 开发理解渲染关系是必须的,也非常重要,很多人忽视了这个过程。 我这里先简单写一下,后面尽量用通俗易懂的方式,举例讲解。 WebGL,全称Web Graphics Library,是一种在网页上渲染3D图形的技术。它…...

人生建议:向猫学习
心安理得地被爱 猫从不担心自己不配得到爱,也正是这幅理所应当、宠辱不惊的样子,让人欲罢不能。或许 当你相信自己值得世界上最好的爱时,你就会拥有。 多晒太阳多睡觉 猫喜欢睡觉,尤其喜欢躺阳光好的地方。阳光和睡眠,…...

软件架构设计属性之三:结构性属性浅析
文章目录 引言一、结构性属性的定义二、结构性属性的关键要素1. 组件化2. 模块化3. 层次化4. 接口定义5. 数据流6. 依赖管理 三、结构性属性的设计原则1. 高内聚低耦合2. 松耦合3. 清晰的接口4. 可维护性5. 可扩展性 四、结构性属性的实现策略1. 组件划分2. 模块化设计3. 接口设…...

JAVA:多线程常见的面试题和答案
请关注微信公众号:拾荒的小海螺 博客地址:http://lsk-ww.cn/ 1、并发编程三要素? 原 子 性 原子性指的是一个或者多个操作,要么全部执行并且在执行的过程中不被其他操作打断,要么就全部都不执行。可 见 性 可见性指多…...

短信平台-平台群发短信
时代的进步带来了我们生活的便利,而其中最受欢迎和广泛应用的方式之一就是通过短信传递信息。在这个飞速发展的数字时代,我们需要一个高效、可靠的短信平台来满足不断增长的通讯需求。而今天,我要向大家推荐的正是这样一款卓越的短信平台——…...

C++:类和对象
一、前言 C是面向对象的语言,本文将通过上、中、下三大部分,带你深入了解类与对象。 目录 一、前言 二、部分:上 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 5.类的作用域 6.类的实例化 7.类的…...

JavaScript条件语句与逻辑判断:解锁代码逻辑的奥秘【含代码示例】
JavaScript条件语句与逻辑判断:解锁代码逻辑的奥秘【含代码示例】 基本概念与作用if...else:决策的基础switch:多路分支的能手逻辑运算符:连接逻辑的纽带三元运算符:简洁的力量 功能使用思路与技巧短路求值优化防止swi…...

sparksql自定义函数
前言 Spark SQL UDF(也称为用户定义函数)是Spark SQL&DataFrame最有用的功能,它扩展了Spark内置功能。在本文中,我将解释什么是UDF?为什么我们需要它,以及如何使用Java、Scala示例在DataFrame和SQL上创建和使用它。 注意:UDF是最昂贵的操作,因此只有在必要时才使用…...

新人开发新系统,旧人维护旧系统
通常来说旧系统存在一些难以解决的问题,软件架构及逻辑实现可能会有一定的缺陷和复杂度,甚至有些烂系统可以称为”焦油坑“,意思是出现问题难以分析解决,谁来谁陷进去。因此,如果同时存在新系统(可能正在开…...

鸿蒙应用模型:【Stage模型开发】概述
Stage模型开发概述 基本概念 下图展示了Stage模型中的基本概念。 图1 Stage模型概念图 [AbilityStage] 每个Entry类型或者Feature类型的HAP在运行期都有一个AbilityStage类实例,当HAP中的代码首次被加载到进程中的时候,系统会先创建AbilityStage实例…...

java使用jdbcTemplatep批量插入数据
JdbcTemplate 是 Spring 框架中提供的一个简化 JDBC 操作的工具类,它封装了 JDBC 的核心功能,使得开发者能够更方便、简洁地进行数据库操作。 下面是一个使用 JdbcTemplate 进行批量插入的示例: import org.springframework.jdbc.core.Batch…...

K8s service 进阶
文章目录 K8s service 进阶Service 工作逻辑Service 具体实现Service 资源类型ClusterIPNodePortLoadBalancerExternalName Service 与 EndpointEndpoint 与 容器探针自定义Endpoint Service 相关字段sessionAffinityexternalTrafficPolicyinternalTrafficPolicypublishNotRead…...

CompletableFuture详细讲解
目录 一、基本概念 1.1 异步编程 1.2 CompletableFuture简介 二、创建和完成CompletableFuture 2.1 创建CompletableFuture对象 2.2 手动完成CompletableFuture 2.3 异常完成CompletableFuture 三、异步计算和回调 3.1 异步任务的执行 3.2 处理计算结果 四、组合多个…...

【Linux】初识Linux和Linux环境配置
1.什么是Linux操作系统 说到电脑系统 我想有大多数人会脱口而出:windows、mac 是的,这也是如今市场上主流的两种操作系统。 但是对于IT相关的人士来说,还有一种系统也是必须有姓名 那就是Linux Linux,Linux Is Not UniX 的…...

redis-cli help使用
1. redis-cli命令使用—先连接上服务器 连接到 Redis 服务器: 使用 redis-cli 命令即可连接到本地运行的 Redis 服务器,默认连接到本地的 6379 端口。 redis-cli如果 Redis 服务器不在本地或者端口不同,可以使用 -h 和 -p 参数指定主机和端…...

中华活页文选高中版投稿发表
《中华活页文选(高中版)》创刊于1960年,是中宣部所属中国出版传媒股份有限公司主管、中华书局主办的国家级基础教育期刊,曾获得“中国期刊方阵双效期刊”、国家新闻出版广电总局推荐的“百种优秀报刊”等荣誉称号。本刊以高中学科…...

[图解]企业应用架构模式2024新译本讲解02-表数据入口
1 00:00:00,420 --> 00:00:04,330 这个案例,我们就是用书上的案例了 2 00:00:06,080 --> 00:00:08,860 收入确认的一个案例 3 00:00:09,510 --> 00:00:11,100 书上讲了,收入确认 4 00:00:13,330 --> 00:00:15,270 就是说,你给…...

SSE(Server Sent Event) 踩坑留念
整条链路是 客户端A --> 服务端 A —> 服务端 B 我负责服务端 A 此时要注意 Client 中的 processes 的写法 Post(value “/v2/xx”, processes MediaType.TEXT_EVENT_STREAM) 这样写是一直报错的 改成下面的写法才可以 Post(value “/v2/xx”, processes MediaT…...

plt.xticks()的作用
参考: https://blog.csdn.net/weixin_41796265/article/details/131442400 plt.xticks() 是 Matplotlib 库中的一个函数,用于设置坐标轴刻度的位置和标签。 它的作用包括: 设置 x 轴刻度的位置:可以通过传递一个数组或列表来设…...

开发者的福音:免去搭建服务,让你的应用开发变得像吃蛋糕一样简单!
传统应用开发的"噩梦" 想象一下,你正在准备一场盛大的晚宴,但必须从零开始建造厨房、种植食材、甚至学习烹饪技巧。这就是传统应用开发的现状——你不仅要设计数据库、编写API接口,还要处理对象存储、实时数据库、云数据库等一系列…...

AVL树的模拟实现
我们上期提到了二叉搜索树,只是简单的讲了一下原理,那么今天我们就讲一下AVL树。 目录 AVL树的概念AVL树的实现AVL树的架构insert插入引用pair对象引进parent指针仅插入数据调节平衡因子情况1:插入在父亲的右边,父亲的平衡因子后…...

php 一个数组中的元素是否在一个字符串中包含
php 一个数组中的元素是否在一个字符串中包含 要检查一个数组中的元素是否在一个字符串中出现,你可以使用strpos()函数。这个函数返回子字符串首次出现的位置索引,如果没有找到,它会返回false。 $array [apple, banana, cherry]; $string …...

conda修改环境名称后,无法安装包,显示no such file
1问题描述 原本创建环境时设置的名字不太合适,但是因为重新创建环境很麻烦,安装很多包。。所以想直接对包名进行修改,本人采用的方式是直接找到conda环境的文件目录,然后修改文件名,简单粗暴。确实修改成功了…...

linux安装mysql【linux】
linux安装mysql【linux】 前言版权推荐CentOS7.9安装mysql8.0【linux】yum安装rpm安装 最后 前言 2024-5-13 15:52:22 以下内容源自《【linux】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星月云 博客主页是https://jss…...

C 语言实例 - 表格形式输出数据
将 1~100 的数据以 10x10 矩阵格式输出。 #include <stdio.h>int main() {int i, j, count;for(i 1; i < 10; i) {for(j i; j <100; j 10 )printf(" %3d", j);printf("\n");}return 0; }运行结果: 1 11 21 31 41 51 61 …...
markdown语法保存
这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…...

数据结构(八)二叉树、哈希查找
文章目录 一、树(一)概念1. 前序遍历:根左右2. 中序遍历:左根右3. 后序遍历:左右根4. 层序遍历:需要借助队列实现 (二)代码实现:二叉树1. 结构体定义2. 创建二叉树1. 注意…...

uniApp 创建Android.keystore证书IOS的证书
Android 证书 1、安装JRE环境 可从Oracle官方下载jre安装包:https://www.oracle.com/technetwork/java/javase/downloads/index.html 打开命令行(cmd),输入以下命令: //切换工作目录到f:路径 D: //将jre命令添加到…...

怎么藏族翻译中文在线翻译?更好地了解藏族文化
怎么藏族翻译中文在线翻译?着全球化的发展,语言交流的重要性日益凸显。藏族,作为中国的一个古老而神秘的民族,其语言对于很多人来说充满了神秘感。然而,在今天的数字化时代,我们有了更多的工具来打破语言壁…...