Jina 实例秀|基于CLIP模型的跨模态视频搜索

news2024/11/18 0:31:30

不同于传统的关键词搜索,你不需要给每个视频素材人为地打上标签。使用开源产品 CLIP-as-service,输入画面的描述文本,直接搜索到对应的视频片段。

CLIP 是一个强大的模型,能够很好地判别文本和图片是否相关,但将其集成到现有系统中需要大量时间精力,以及机器学习知识。

CLIP-as-service 是一种易于使用的服务,具有低延迟和高度可扩展性,可以作为微服务轻松集成到现有解决方案中。也就是说,想要实现视频中的效果,不需要 GPU,不需要安装复杂依赖,只需要使用几个 Python 函数,CLIP-as-service 将完成所有工作。

本项目通过提取出视频的关键帧,分割视频的关键片段,巧妙地将 文字搜索视频 的任务转化成为 文字搜索图片 的任务。在完成关键帧抽取后,通过将查询文本和关键帧图集传给 CLIP-as-service,即可返回与查询文本匹配的视频片段。

项目仓库:https://github.com/jemmyshin/Video-CLIP-Indexer

预备工作

首先,在新的 Python 3 虚拟环境中,安装 docarrayclip_client

pip install clip_client "docarray[full]>=0.20.0

同时,你还需要一个用于 CLIP-as-service 的 Token,👉 获取路径请参考:CLIP-as-service 新升级!

获取数据

DocArray 是一个用于处理、传输和存储多模态数据的 Python 工具包,提供了非常便捷的多模态数据处理功能。使用 DocArray 加载 MP4 视频只需两行代码:

from docarray import Document

video_data = Document(uri='89757.mp4')
video_data.load_uri_to_video_tensor()
print(video_data.tensor.shape)
(12116, 720, 480, 3)

对于视频数据来说,.tensor 是一个四维数组。本示例视频有 12,116 帧,视频尺寸为 720x480,每个像素具有 3 个颜色维度。使用 DocArray 你可以按照帧的编号逐一查看各个帧,也可以提供开始和结束的帧编号提取剪辑。例如:

# 显示第 1400 帧
Document(tensor=numpy.rot90(video_data.tensor[1400], -1)).display()

8be4a62ece468280da725e73f8da32f9.png

猫和老鼠-西部牛仔-第1400帧

# 显示从 3100 帧到 3500 帧
clip_data = video_data.tensor[3100:3500]
Document(tensor=clip_data).save_video_tensor_to_file("clip.mp4")
Document(uri="clip.mp4").display()

提取关键帧

关键帧指角色或物体运动变化时关键动作所处的那一帧。

094999ae7414aaa35bee91fa9055f958.png

在加载视频时,DocArray 使用Document.load_uri_to_video_tensor()方法,自动收集关键帧,并存储在 Document.tagskey 字典的 keyframe_indices

比如在本示例视频中,关键帧有:

print(video_data.tags['keyframe_indices'])

[0, 150, 300, 450, 600, 750, 900, 1050, 1200, 1350, 1500, 1650, 1800, 1950, 2100, 2250, 2400, 2550, 2700, 2850, 3000, 3150, 3300, 3450, 3600, 3750, 3900, 4050, 4200, 4350, 4500, 4650, 4800, 4950, 5100, 5250, 5400, 5550, 5700, 5850, 6000, 6150, 6300, 6450, 6600, 6750, 6900, 7050, 7200, 7350, 7500, 7650, 7800, 7950, 8100, 8250, 8400, 8550, 8700, 8850, 9000, 9150, 9300, 9450, 9600, 9750, 9900, 10050, 10200, 10350, 10500, 10650, 10800, 10950, 11100, 11250, 11400, 11550, 11700, 11850, 12000]

接着就可以根据关键帧,把文字视频搜索的任务转化成为图片搜索的任务。

执行搜索

首先,我们将所有关键帧提取成图像,并将每个关键帧放入自己的 Document,然后将所有帧编译成一个 DocumentArray 对象:

from docarray import Document, DocumentArray
from numpy import rot90

keyframe_indices = video_data.tags['keyframe_indices']
keyframes = DocumentArray()
for idx in range(0, len(keyframe_indices) - 1):
 keyframe_number = keyframe_indices[idx]
    keyframe_tensor = rot90(video_data.tensor[keyframe_number], -1)
    clip_indices = {
        'start': str(keyframe_number),
        'end': str(keyframe_indices[idx + 1]),
    }
    keyframe = Document(tags=clip_indices, tensor=keyframe_tensor)
    keyframes.append(keyframe)

上面的代码使用 Document.tags 字典来存储开头和结束的关键帧编号,以便提取对应的视频剪辑。

接着我们使用 CLIP-as-service,将查询文本(在示例中为“戴着白色礼帽的汤姆猫”)和关键帧图像集合传输给它,它将返回和查询文本相似的图像:

from docarray import Document, DocumentArray
from clip_client import Client

server_url = "grpcs://api.clip.jina.ai:2096"

# substitute your own token in the line below!
jina_auth_token = "54f0f0ef5d514ca1908698fc6d9555a5"

client = Client(server_url,
                credential={"Authorization": jina_auth_token})
query = Document(text="Tom cat wearing a white bowler hat", matches=keyframes)
ranked_result = client.rank([query])[0]

我们将查询和关键帧图像传输到 Jina AI Cloud,CLIP-as-service 为文本查询和每个关键帧计算嵌入向量。然后,我们测量关键帧向量和文本查询向量之间的距离。我们返回一个关键帧列表,这些关键帧按它们与嵌入空间中的文本查询的接近程度排序。

将查询和关键帧图像传输到 Jina AI Cloud,然后 CLIP-as-service 就会为查询文本和每个关键帧计算 embedding。计算完成关键帧向量和查询文本向量之间的距离后,CLIP-as-service 就会返回在嵌入空间中与文本查询的按照相似程度排序的关键帧列表。

e17f4903db52a0cf3285c9bea10485b0.png

CLIP 将文本和图像转换为公共嵌入空间中的向量,其中它们之间的距离反映了它们的语义相似性。与其他图像相比,戴着礼帽的汤姆图像的嵌入向量比其他图像更接近文本“戴着白色礼帽的汤姆猫”的向量。

查询按照最佳匹配到最差匹配的顺序重新排列 Document.matches 中的关键帧图像。

print(ranked_result.matches[0].tags)

{'start': '2105', 'end': '2184'}

你可以在 Document.tags 看到,我们保留了关于此关键帧的信息:它从第 2105 帧到第 2184 帧。有了这些信息,我们就可以获取与之匹配的视频片段:

match = ranked_result.matches[0]
start_frame = int(match.tags['start'])
end_frame = int(match.tags['end'])
clip_data = video_data.tensor[start_frame:end_frame] 
Document(tensor=clip_data).save_video_tensor_to_file("match.mp4")
Document(uri="match.mp4").display()

作者简介

付杰,Jina AI 机器学习工程师

Scott,Jina AI 高级布道师

原文链接

https://jina.ai/news/want-search-inside-videos-like-pro-clip-service-can-help/

更多资料

[1]

文档: https://clip-as-service.jina.ai/

[2]

GitHub: https://github.com/jina-ai/clip-as-service

[3]

获取 Token: https://console.clip.jina.ai/get_started

更多技术文章

📖 Jina AI创始人肖涵博士解读多模态AI的范式变革

🎨 语音生成图像任务|🚀 模型微调神器Finetuner

💨 DocArray + Redis:快到飞起来的推荐系统

😎 Jina AI正式将DocArray捐赠给Linux基金会

🧬 搜索是过拟合的生成;生成是欠拟合的搜索

fe5ae92830627521ea875c0a22a5cad0.png

点击“阅读原文”,即刻了解 Jina

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/125460.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LeetCode】验证二叉搜索树 [M]

98. 验证二叉搜索树 - 力扣(LeetCode) 一、题目 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下: 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。…

微信小程序框架02

目录 1.框架简介 2.视图层 View 2.2 WXML 2.3 WXSS 2.4 JS 3.事件 4.逻辑层 APP service 4.1 生命周期 4.2 页面路由 4.3模块化 1.框架简介 小程序开发框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务。 整个小程序框架系统分为两部…

山东大学机器学习课程资源索引

实验 完整实验代码获取 github repo 【ML实验4】多分类贝叶斯模型 【ML实验5】SVM(手写数字识别、核方法) 【ML实验6】K-means(图像压缩) 【ML实验7】人脸识别综合项目(PCA、多分类SVM) 一个PCA加速技巧 …

数据治理:企业数据治理蓝图

参考《一本书讲透数据治理》、《数据治理》等 文章目录企业数据治理体系企业数据治理9个要素企业数据治理4个层面企业数据治理之道企业数据治理之法企业数据治理之术企业数据治理之器企业数据治理体系 数据治理、数据管理、数据管控三者是什么关系?很多人都搞混&am…

【Spring(二)】IoC入门案例(XML版)

文章目录前言1.IoC入门案例总结前言 上篇文章我们讲了IOC和DI两个核心概念,本篇文章我们会在Spring的环境下来实现它们💪💪。 1.IoC入门案例 我们先来实现IoC也就是管理Bean的这套模式,我们先来说说这套程序应该怎么做&#xff0c…

深度学习Week12-训练自己的数据集(YOLOv5)

这周接着详细解析小白YOLOv5全流程-训练实现数字识别_牛大了2022的博客-CSDN博客_yolov5识别数字,上周入门教大家下载配置环境,如果没有的话请参考上周的文章深度学习Week11-调用官方权重进行检测(YOLOv5)_牛大了2022的博客-CSDN博…

《IDC MarketScape:2022全球通用计算机视觉厂商评估》出炉,腾讯云智能入选

近日,全球领先的IT市场研究和咨询公司IDC发布了2022年度《MarketScape:全球通用计算机视觉厂商评估》报告(以下简称“报告”),腾讯云智能凭借在计算机视觉领域领先的技术积累、出色的产品能力和丰富的行业落地实践&…

案例分享:硬件敏捷

“没有人能够在硬件领域推动以两周为单位的循环迭代!”当人们谈起敏捷方法在包含了硬件及软件产品开发时,第一反应都是类似的论调。然而,已经有一些团队,尝试将已有的可靠硬件开发理念与少量从敏捷软件中借鉴的新鲜思想结合&#…

系统日志- Journal and Rsyslog

Log文件 Rsyslog 的配置文件/etc/rsyslog.conf Rsyslog的旧的信息会在最前面,新的信息会在最下面。 tail -f /var/log/messages #可以动态监控日志信息logger 发送日志信息 logger -p user.notice #“内容” -p选项测试实验: 1.在/etc/rsyslog.d/文…

基于ThinkPHP框架开发的全套家政服务小程序源码(带调试视频)

家政服务小程序源码 在线派单 商家入驻 多城市带积分开源小程序 了解更多内容可私信我。 1、独立版 ThinkPHP框架 后端全开源; 2. 开发语言:PHP; 3. 数据库:MySQL; 4.小程序端:Uniapp; 5.…

Vuex基础概念用法(新手入门)

一.Vuex概念及解释 定义: vue全局状态管理器。有了Vuex在任意组件/页面都可以访问vuex数据,当数据更新的时候,引用vuex的组件视图会自动更新。也就是说Vuex实现数据全局共享,响应式更新。 1.state(存放状态) $store…

《flask》flask+mqtt联动快速上手

简介 本文旨在介绍如何快速上手联动flask mqtt,本文将会给出一个简单的demo,用于演示在如何通过访问flask接口来触发mqtt,并在flask运行的基础的上对mqtt进行订阅。 快速上手 因为有项目需求,所以需要flask mqtt进行联动&…

Docker网络中篇-docker网络的四种类型

通过上一篇学习,我们对docker网络有了初步的了解。本篇,咱们就来实战docker网络。 docker网络实战 实战docker网络,我们将从以下几个案例来讲解 1:birdge是什么? 2:host 3:none 4:container 实战网络类型如下: 在docker中,网络的配置是以json格式存在的,下面…

知识变现创业者必读——《知识变现实操手册》

现在越来越多人,正在跑步进入知识变现创业这个赛道。 为什么进入这个赛道,因为能赚钱钱啊,大部分人是受到了知识变现大咖们日入万元,月入十万,这些赚钱效益的刺激,匆忙进入的。 我问一句,你知识…

网络路由技术和协议

网络路由是网络通信的重要组成部分。路由可帮助您的网络组件从可用选项中选择最佳网络路径。这使得网络通信高效可靠。启用此功能的硬件组件称为路由器。监控和管理路由器是网络管理员日常工作中不可或缺的一部分。由于路由器可以决定网络连接和可用性的成败,因此了…

MATLAB-plot绘图函数

plot函数是MATLAB中最核心的二维绘图函数,它有多种语法格式可以实现多种功能。 plot函数的基本调用格式如下。 plot(y) 当y为向量时,是以y的分量为纵坐标、元素序号为横坐标,用直线依次连接数据点, 绘制曲线。若y为实矩阵&#…

【技术分享】如何实现功能完备性能优异的RTMP、RTSP播放器?

技术背景 这几年,我们对接了太多有RTSP或RTMP直播播放器诉求的开发者,他们当中除了寻求完整的解决方案的,还有些是技术探讨,希望能借鉴我们播放端的开发思路或功能特性,完善自己的产品。 忙里偷闲,今天我…

【GO】K8s 管理系统项目[API部分--Pv]

K8s 管理系统项目[API部分–Pv] 1. 接口实现 service/dataselector.go type pvCell corev1.PersistentVolumefunc(p pvCell) GetCreation() time.Time {return p.CreationTimestamp.Time }func(p pvCell) GetName() string {return p.Name }2. Pv功能 service/pv.go 2.1 获…

沙龙预告|2023 年展望 Web3 Crypto

全长 621 字,预计阅读 3 分钟 作者:MiX 起起落落的2022年即将结束,随着传统金融机构的采用和 Web3 创新的不断深入,加密领域已经成为全球资本和技术创新的重要组成部分。 总结2022,展望2023,这对每一位加…

【数据库与缓存保持一致性】

文章目录1. 方案1先更新数据库,再更新缓存先更新缓存,在更新数据库2. 方案2先更新数据库,在删缓存先删缓存,在更新数据库3. 方案3—如何保证两个操作都能执行成功?重试机制订阅 MySQL binlog1. 方案1 先更新数据库&am…