当前位置: 首页 > article >正文

SAM2:使用mask作为提示输入,实现VOS视频分割

8k50o45u_seg目录1. 引言2. 使用SAM2实现VOS任务2.1 数据集2.2 主要函数2.3 主要代码3. 结果展示1. 引言本文尝试使用SAM2模型来实现VOS任务。由于在官方的github代码中只找到了point或者box作为提示但是论文中却说明是可以输入mask作为提示的所以打算自己尝试一下。官方githubhttps://github.com/facebookresearch/sam22. 使用SAM2实现VOS任务2.1 数据集本文是基于MOSE数据集来进行实验。MOSE 数据集是一个用于视频目标分割Video Object Segmentation, VOS的数据集主要用于评估像 Segment Anything Model 2 这类模型在复杂视频场景中的分割与跟踪能力。MOSE数据集https://mose.video/数据集的格式如下每一个视频都处理一个帧列表train/valid.tar.gz │ ├── Annotations │ ├── video_name_1 │ │ ├── 00000.png │ │ ├── 00001.png │ │ └── ... │ └── video_name_... │ └── ... │ └── JPEGImages ├── video_name_1 │ ├── 00000.png │ ├── 00001.png │ └── ... └── video_name_... └── ...2.2 主要函数在VOS任务中通常会使用第一帧的mask图像作为提示输入然而MOSE数据中的标注是彩色的mask每一种颜色代表一种类别如下图所示而SAM2中所需要的mask提示需要为 Binary Mask所以需要对MOSE数据集中的mask进行处理提取出每一个类别的掩码图。将每种颜色拆分成为单独的 Binary mask图像并保存到列表中。def split_multiclass_mask(mask_path, ignore_backgroundTrue): 读取多类别 mask并将每种颜色拆分成单独的二值 mask 参数: mask_path: mask图像路径 ignore_background: 是否忽略背景(默认忽略黑色) 返回: binary_masks: list每个元素是一个 H×W 的二值 mask colors: 每个 mask 对应的颜色 mask cv2.imread(mask_path) if mask is None: raise ValueError(f无法读取 mask: {mask_path}) # 获取所有颜色 colors np.unique(mask.reshape(-1, 3), axis0) binary_masks [] valid_colors [] for color in colors: # 跳过背景 if ignore_background and np.all(color [0, 0, 0]): continue # 找到该颜色的位置 m np.all(mask color, axis-1) binary_mask (m * 255).astype(np.uint8) binary_masks.append(binary_mask) valid_colors.append(color) return binary_masks, valid_colors虽然输入需要binary mask但是最终生成的掩码图应该是彩色的mask所以使用generate_mask函数生成彩色mask为每一个id生成一种颜色。def generate_mask(obj_id, mask): mask np.squeeze(mask) H, W mask.shape # 生成颜色 cmap plt.get_cmap(tab10) color np.array(cmap(obj_id % 10)[:3]) * 255 color color.astype(np.uint8) # 初始化黑图 mask_img np.zeros((H, W, 3), dtypenp.uint8) mask_bool mask.astype(bool) # 填充颜色 mask_img[mask_bool] color return mask_img本文中希望最终生成的结果是带有掩码的视频和彩色mask图像def merge_masks_and_overlay(frame, all_masks, alpha0.5): frame: 原图 (H,W,3), dtypeuint8 all_masks: list每个元素是 (H,W,3) 彩色mask, dtypeuint8 alpha: 叠加透明度 return: merged_mask : 合并后的mask图 (H,W,3) overlay_img : 原图mask叠加 (H,W,3) H, W frame.shape[:2] # 1 初始化 mask merged_mask np.zeros((H, W, 3), dtypenp.uint8) # 2 合并所有mask for m in all_masks: mask_bool np.any(m 0, axis2) merged_mask[mask_bool] m[mask_bool] # 3 叠加到原图 overlay frame.copy() mask_area np.any(merged_mask 0, axis2) # 使用 numpy 做叠加 overlay[mask_area] ( alpha * merged_mask[mask_area].astype(np.float32) (1 - alpha) * overlay[mask_area].astype(np.float32) ).astype(np.uint8) # cv2.imwrite(frame.png, overlay) return merged_mask, overlay2.3 主要代码配置模型与保存路径if torch.cuda.is_available(): device torch.device(cuda) elif torch.backends.mps.is_available(): device torch.device(mps) else: device torch.device(cpu) print(fusing device: {device}) if device.type cuda: # use bfloat16 for the entire notebook torch.autocast(cuda, dtypetorch.bfloat16).__enter__() # turn on tfloat32 for Ampere GPUs (https://pytorch.org/docs/stable/notes/cuda.html#tensorfloat-32-tf32-on-ampere-devices) if torch.cuda.get_device_properties(0).major 8: torch.backends.cuda.matmul.allow_tf32 True torch.backends.cudnn.allow_tf32 True elif device.type mps: print( \nSupport for MPS devices is preliminary. SAM 2 is trained with CUDA and might give numerically different outputs and sometimes degraded performance on MPS. See e.g. https://github.com/pytorch/pytorch/issues/84936 for a discussion. ) if __name__ __main__: sam2_checkpoint sam2/checkpoints/sam2.1_hiera_large.pt model_cfg configs/sam2.1/sam2.1_hiera_l.yaml video_path sam2/MOSE_val/JPEGImages anno_path sam2/MOSE_val/Annotations output_dir output/MOSE obj_num 1 os.makedirs(output_dir, exist_okTrue) shutil.rmtree(output_dir) file_count 1 predictor build_sam2_video_predictor(model_cfg, sam2_checkpoint, devicedevice) for file in os.listdir(video_path): if file_count 1: predictor.reset_state(inference_state) torch.cuda.empty_cache() frames_path os.path.join(video_path, file) mask_path os.path.join(anno_path, file, os.listdir(os.path.join(anno_path, file))[0]) video_save_path os.path.join(output_dir, video,file) mask_save_path os.path.join(output_dir, masks,file) os.makedirs(video_save_path, exist_okTrue) os.makedirs(mask_save_path, exist_okTrue)接下来对彩色mask图像进行处理并且将视频帧按顺序排列这一步非常重要不然可能会导致输入的提示mask与输入的帧不一致也是为了保证后续生成符合顺序的掩码视频# 处理mask图像 binary_masks, valid_colors split_multiclass_mask(mask_path) # 对帧按顺序排列 frame_names [ p for p in os.listdir(frames_path) if os.path.splitext(p)[-1].lower() in [.jpg, .jpeg, .png] ] frame_names.sort(keylambda p: int(os.path.splitext(p)[0]))初始化predictor后输入提示掩码注意每一种类别对应着一种obj_id每一个类别对应着的binary mask都需要输入一次不能一次性输入。inference_state predictor.init_state(video_pathframes_path) # take a look the first video frame frame_idx 0 obj_id 1 for mask in binary_masks: _, out_obj_ids, out_mask_logits predictor.add_new_mask( inference_state, frame_idx, obj_id, mask, ) obj_id 1用 SAM2 的视频传播propagation功能对视频每一帧生成目标的分割 mask并把结果保存到video_segments字典中。video_segments {} # video_segments contains the per-frame segmentation results for out_frame_idx, out_obj_ids, out_mask_logits in predictor.propagate_in_video(inference_state): video_segments[out_frame_idx] { out_obj_id: (out_mask_logits[i] 0.0).cpu().numpy() for i, out_obj_id in enumerate(out_obj_ids) }最后生成结果output_video os.path.join(video_save_path, f{file}_seg.mp4) # 读取第一帧获取尺寸 first_img cv2.imread(os.path.join(frames_path, frame_names[0])) h, w, _ first_img.shape # 创建 VideoWriter out iio.get_writer( output_video, fps5, # 保持 RGB macro_block_size1 ) for frame_idx in range(len(frame_names)): img_path os.path.join(frames_path, frame_names[frame_idx]) frame cv2.imread(img_path) all_masks [] if frame_idx in video_segments: for out_obj_id, out_mask in video_segments[frame_idx].items(): obj_mask_img generate_mask(out_obj_id, out_mask) all_masks.append(obj_mask_img) merge_mask, overlay_frame merge_masks_and_overlay(frame, all_masks) cv2.imwrite(os.path.join(mask_save_path, frame_names[frame_idx]), merge_mask) cv2.imwrite(overlay.png, overlay_frame) overlay_frame cv2.cvtColor(overlay_frame, cv2.COLOR_BGR2RGB) out.append_data(overlay_frame) out.close() print(Saved video:, output_video) file_count 13. 结果展示抽取了一个视频中的前几帧mask结果展示jxmcdk8k_seg

相关文章:

SAM2:使用mask作为提示输入,实现VOS视频分割

8k50o45u_seg目录 1. 引言 2. 使用SAM2实现VOS任务 2.1 数据集 2.2 主要函数 2.3 主要代码 3. 结果展示 1. 引言 本文尝试使用SAM2模型来实现VOS任务。由于在官方的github代码中只找到了point或者box作为提示,但是论文中却说明是可以输入mask作为提示的&#…...

vue+uniapp小程序Python美食菜品点餐订单系统

目录 技术选型与架构设计前端功能模块划分后端API开发关键实现细节测试与部署 项目技术支持可定制开发之功能创新亮点源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作 技术选型与架构设计 前端采用Vue.jsUniapp框架,实现跨平台小…...

Element Plus - 在 el-select 的每个选项右侧添加按钮

在 el-select 的每个选项右侧添加按钮 <el-select v-model"formData.encryptMethod" placeholder"请选择加密方式"><el-option v-for"item in encryptMethods" :key"item.value" :label"item.label" :value"i…...

C++编程法则365天(359)lamba是如何捕获变量

文章目录 一、Lambda捕获的核心前提:Lambda的本质是“匿名仿函数” 二、不同捕获方式的实现细节 1. 值捕获([x] 或 [=]) 2. 引用捕获([&x] 或 [&]) 3. 捕获this指针([this] 或 [=]/[&] 在类中) 4. 隐式捕获([=] 或 [&]) 5. C++14新增:初始化捕获([x…...

线性参变(LPV)+输出反馈鲁棒模型预测控制(OFRMPC)+路径跟踪(PTC)

线性参变(LPV)输出反馈鲁棒模型预测控制(OFRMPC)路径跟踪(PTC)&#xff0c;目前能实现20-25m/s的变速单移线&#xff0c;更多工况可自行调试。 考虑速度和侧偏刚度变化,以及质心侧偏角的鲁棒估计&#xff0c;基于二自由度模型和LMI设计输出反馈鲁棒模型预测控制器。 上层考虑输…...

双极板设计经验

1.气体流通方向在双极板中通常有流场的那一面朝里&#xff0c;双极板有出口和入口&#xff0c;气体通过这些垂直进出板子&#xff0c;然后在流场的沟内平行与板子迅速铺满整个流场&#xff0c;再通过流场的肋流向扩散层。2.出入口设计出口的总面积应略大于入口的总面积&#xf…...

Python基础分享:打印各种三角形和九九乘法表

学习编程时&#xff0c;循环和字符串操作是必须掌握的基础知识。通过打印简单的图形&#xff0c;我们可以直观地理解循环的逻辑、字符串的拼接以及格式化输出。本文将以Python为例&#xff0c;详细介绍如何打印正三角形、倒三角形、等腰三角形以及经典的九九乘法表&#xff0c;…...

深度优先搜索:从全排列到记忆化搜索

深度优先搜索&#xff08;DFS&#xff09;的进化之路&#xff1a;从全排列到记忆化搜索 在算法竞赛中&#xff0c;搜索算法是解决问题的基础。然而&#xff0c;面对不同类型的问题&#xff0c;选用错误的 DFS 模型不仅会导致超时&#xff08;TLE&#xff09;&#xff0c;还容易…...

技术深潜:从向量检索到语义对齐——解析天津市南开区天才群策科技有限责任公司的GEO工程化实践

技术前言&#xff1a;当企业营销遭遇模型黑盒 在CSDN的技术社区里&#xff0c;关于GEO的讨论早已从“是什么”转向了“怎么做”。随着各大AI平台算法的快速迭代&#xff0c;传统的SEO技术栈已全面失效。企业面临的核心矛盾在于&#xff1a;大模型的知识更新是非线性的&#xff…...

D3DCompiler_47.dll未被指定在Windows运行的问题解决办法

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…...

一文读懂OpenClaw!开源、可自托管的个人Agent平台

OpenClaw 是 2026 年备受关注的开源 AI Agent 平台&#xff0c;它并非普通的聊天 AI&#xff0c;而是 AI 智能 体理论的成熟工程化实践&#xff0c;不仅能聊天&#xff0c;更能帮你执行具体处理任务。想要用好这一工具&#xff0c;首先要厘清其底层的基础逻辑。 OpenClaw基础概…...

vue2和vue3使用less和scss

文章目录Vue 2 中使用 Less 和 SCSS一、安装依赖二、配置 vue.config.js三、在 .vue 文件中使用Vue 3 中使用 Less 和 SCSS一、安装依赖二、配置 vite.config.js三、在 .vue 文件中使用Vue 2和Vue 3使用差异样式穿透less、scss语法1、变量2、运算3、注释4、嵌套5、混入(Mixin)6…...

3.29不见不散

...

超越 Transformer 的架构前瞻

第六章&#xff1a;未来——超越 Transformer 的架构前瞻Transformer 的成功令人瞩目&#xff0c;但在工程和科学的世界里&#xff0c;没有任何架构是完美的。Transformer 有它的阿喀琉斯之踵&#xff0c;全球顶尖实验室正在积极探索下一代架构。这一章我们来剖析 Transformer …...

面试官最爱问的设计题:动态支付系统设计(策略模式 + 工厂模式 + Spring自动注册)

在 Java 面试中&#xff0c;有一道 非常经典的面向对象设计题&#xff1a;如何设计一个 支持多种支付方式的支付系统&#xff1f;例如&#xff1a;支付宝微信银行卡Apple Pay未来可能新增更多支付方式很多面试者第一反应就是写 if-else&#xff0c;但这其实是一个 典型的设计模…...

部署RHCSA9.7、并完成优化

一、建立虚拟机 1、初步建立 &#xff08;1&#xff09;点击创新的虚拟机 &#xff08;2&#xff09;点击自定义----下一步 &#xff08;3&#xff09;点击稍后安装操作系统----下一步 &#xff08;4&#xff09;点击Linux&#xff08;L&#xff09;----版本选择&#xff08;…...

分享一款高颜值强大的uniapp组件库-图鸟组件库

图鸟UI是一套基于uni-app的组件库&#xff0c;提供了丰富的UI组件和完整的页面模板&#xff0c;可以帮你快速搭建小程序、H5或App。下面整理了官方模板和社区资源的入口&#xff0c;方便你直接选用。 &#x1f3a8; 官方模板系列 图鸟官方提供了多种场景的完整模板&#xff0…...

深度探讨:从 OpenClaw 爆火,看 AI Agent 的真相与程序员的未来

导语&#xff1a; 近期&#xff0c;以 OpenClaw 为代表的自主智能体&#xff08;Autonomous Agent&#xff09;火爆技术圈。这些宣称能“完全接管电脑、自主写代码”的 AI 到底有多神&#xff1f;在狂热的炒作背后&#xff0c;技术落地的真相是什么&#xff1f;AI 真的要干掉程…...

AI博主实测|2026最新PPT工具合集,覆盖全场景,告别熬夜手搓

一、引言作为常年和PPT打交道的AI博主&#xff0c;每天都会收到粉丝提问&#xff1a;“做PPT用什么工具高效&#xff1f;”“AI能帮我快速做PPT吗&#xff1f;”“新手零基础&#xff0c;哪款工具最容易上手&#xff1f;”其实PPT工具没有“最好”&#xff0c;只有“最适配”—…...

原生Windows安装OpenClaw

前言 根据OpenClaw官方文档&#xff0c;Windows下安装其实是推荐WSL2&#xff0c;但我的电脑上没有提前装Linux虚拟机&#xff0c;又只是想先快速体验一下OpenClaw&#xff0c;因此就原生Windows安装了。 部署前准备 官方文档中&#xff0c;有几种安装方式。 方式一 通过在W…...

02-Agent 智能体开发实战指南(二):工具调用系统

Agent 智能体开发实战指南&#xff08;二&#xff09;&#xff1a;工具调用系统深度解析 系列导读&#xff1a;这是《Agent 智能体开发实战指南》系列的第二篇&#xff0c;将深入讲解 Agent 的工具调用系统&#xff0c;包括tool 装饰器原理、工具设计原则、多工具协作等核心内容…...

AI大模型课程|非计算机专业转行人工智能,好就业吗?非常详细收藏我这一篇就够了

很多就业者在看到人工智能领域发展的很好&#xff0c;意识觉醒的人想进入这个行业里面得到一些新兴行业的红利&#xff0c;想转行却担心自己的经历或者是专业被卡&#xff0c;犹豫不决&#xff0c;今天就来和大家聊一聊这个话题&#xff0c;看看能不能解除你的疑惑。 01写在前面…...

2026春招AI人才暴涨12倍!高薪缺人,企业招聘“去初级化”,脉脉洞察求职新趋势!

近日&#xff0c;职场社区平台脉脉发布《社交求职——2026年1-2月中高端人才求职招聘洞察》&#xff08;以下简称《洞察》&#xff09;。《洞察》显示&#xff0c;2026年1-2月&#xff0c;招聘市场整体回暖。新经济行业岗位量增长12.77%。AI人才争夺成招聘主战场&#xff0c;岗…...

OpenClaw深度解析:AI Agent运作机制全拆解,揭秘智能边界与安全风险!

本课以 OpenClaw 为具体案例&#xff0c;系统拆解 AI Agent 的完整运作机制。核心逻辑链为&#xff1a;LLM文字接龙本质 → System Prompt驱动的身份认知构建 → Tool Call工具链执行&#xff08;Read/Write/exec/TTS/ASR递归调用&#xff09;→ Sub-agent层级外包与Context En…...

Coursera 6 大 AI 爆款课深度评测!告别理论堆砌,初级开发者也能秒懂选课攻略,简历瞬间加分!

市面上 AI 课程一大堆&#xff0c;但要么太理论&#xff0c;要么太基础。本文对 Coursera 上 6 门优质 AI 课程进行了评测&#xff0c;结合国内初级开发者视角&#xff0c;帮你看懂各课程适合什么人、侧重点是什么&#xff0c;以及如何按自己的起点与目标做出选课决策。导语 想…...

ebmap Tour 智慧节目时间表功能预览

ebmap Tour 最近新增了节目时间表功能&#xff0c;为景区 / 园区打造实时化、场景化的演艺活动管理与展示体系&#xff0c;让游客清晰掌握节目动态、合理规划游览路线&#xff0c;同时帮助运营方高效编排、精准触达游客&#xff0c;提升景区服务体验与活动曝光。安装扩展&#…...

约瑟夫环(代码+公式推导)

题目描述&#x1d45b;个人的编号是 1 ~ &#x1d45b;&#xff0c;如果他们依编号按顺时针排成一个圆圈&#xff0c;从编号是 1 的人开始顺时针报数。&#xff08;报数是从 1 报起&#xff09;当报到 &#x1d458;的时候&#xff0c;这个人就退出游戏圈。下一个人重新从 1 开…...

图解C语言侵入式双向循环链表与 container_of 宏底层原理

一、侵入式链表 在了解侵入式链表之前&#xff0c;先回顾之前的非侵入式链表&#xff0c;形式如下&#xff1a; struct Node {int data; // 数据struct Node* next; };在非侵入式链表的这种设计中&#xff0c;拿到一个 Node&#xff0c;顺便也就拿到了它的 data。 …...

java从头开始-苍穹外卖-day11-数据统计与展示

营业额统计用户统计订单统计销量排名top10这个其实要多表联查&#xff0c;菜品是在订单详情表&#xff0c;但是这个表没有订单完成状态&#xff0c;因此需要多表连查...

别让Service层“越界”:为何Java中Service层不该直接返回Result对象?

别让Service层“越界”&#xff1a;为何Java中Service层不该直接返回Result对象&#xff1f; 引入&#xff1a;一次代码审查引发的思考 昨天在进行代码审查的时候&#xff0c;我发现同事在 Service 层直接返回了 Result 对象。当时我就指出了这个问题&#xff0c;可同事一脸疑惑…...