YOLOv8+CLIP实现图文特征匹配

本文通过结合YOLOv8s的高效物体检测能力与CLIP的先进图像-文本匹配技术,展示了深度学习在处理和分析复杂多模态数据中的潜力。这种技术的应用不仅限于学术研究,还能广泛应用于工业、商业和日常技术产品中,以实现更智能的人机交互和信息处理。

一、物体检测与图像处理

1. 物体检测模型:YOLOv8s

  物体检测是计算机视觉领域的核心问题之一,它涉及识别图像中的物体并精确地定位它们的位置。YOLO(You Only Look Once)技术自2016年由Redmon等人首次提出以来,就以其高效的处理速度和优秀的性能引领了物体检测领域。YOLO的核心创新是将物体检测任务视为一个端到端的回归问题,通过单次前向传播,同时预测图像中多个边界框和相应的类别概率。YOLOv8s是YOLO系列中的最新迭代,继承并增强了YOLO体系的主要优点,如实时性能和高准确率。YOLOv8s进一步优化了模型架构和训练过程,使用深度卷积神经网络一次性分析整个图像,从而预测物体的类别和位置。这种端到端的训练方式不仅简化了训练过程,还增强了模型对不同尺寸物体的泛化能力。

  在本文中,我们采用预训练的YOLOv8s模型进行物体检测。该模型接受输入的原始图像,并输出包括物体类别、置信度和边界框坐标在内的详细检测信息,为后续的图像处理和分析奠定了基础。

在这里插入图片描述

2. 图像处理过程

  图像处理流程从使用PIL(Python Imaging Library)库加载图像开始,这是一个广泛应用于Python中的图像处理库。图像加载后,即被输入到YOLOv8s模型进行推断处理。模型输出的结果包括每个检测到的物体的类别、置信度和边界框坐标。基于这些信息,在原始图像上绘制边界框和相应的标注信息,如物体的类别和置信度,这样的视觉呈现有助于我们直观地理解和评估模型的检测效果。

  代码中还实现了一个关键步骤:根据检测到的边界框坐标,将每个物体裁剪出来并保存为独立的图像文件。这一处理步骤极为重要,因为它允许对每个单独检测到的物体进行进一步分析,无论是用于进一步的图像处理任务,还是用作其他应用,如机器学习训练数据集的构建。

  通过这种方法,我们不仅提高了对物体检测技术的理解,还能有效地利用检测结果进行多种后续的图像分析任务,展示了计算机视觉技术在实际应用中的广泛可能性。

在这里插入图片描述

二、图像与文本的语义匹配.

  1. CLIP模型技术介绍

  CLIP(Contrastive Language-Image Pre-training)是由OpenAI开发的一种革命性多模态学习框架,设计目的是为了深入理解图像与文本之间的语义联系。此框架基于大规模对比学习的原则,通过并行训练图像编码器和文本编码器来识别图像与其描述之间的匹配关系,显著提升了模型对视觉任务的泛化能力。CLIP模型的核心优势在于其独特的训练方法,该方法采用海量的图像-文本对作为训练数据,通过优化图像和文本表示之间的相似度进行训练。这种策略使得CLIP不仅能理解广泛的视觉概念,还能将这些概念与自然语言有效结合,从而实现深层次的语义理解。

  在本文中,我们采用了预训练的CLIP模型(ViT-B/32版本),该模型结合了视觉Transformer(ViT)架构和先进的文本处理能力,使其能够处理高维度的图像数据及复杂的文本输入。

  1. 图像与文本的预处理与特征提取

  为了有效利用CLIP模型进行图像与文本的匹配,数据的适当预处理至关重要。图像数据经过CLIP提供的标准预处理流程,包括调整尺寸、归一化等步骤,确保符合模型的输入规范。文本数据则通过CLIP的分词器处理,将文本转换为一系列标记,进而转换为数值型向量,以适配模型的处理需求。

  在特征提取阶段,预处理后的图像和文本数据分别输入到CLIP的图像编码器和文本编码器中。这两个编码器分别为图像和文本生成高维的特征表示,这些表示在多维空间中捕捉并表达了图像和文本的深层语义内容。

  1. 相似度计算与分析

  获取图像和文本的特征表示后,下一步是计算它们之间的语义相似度。这通过计算两组特征向量之间的点积来实现,其中点积结果反映了图像与文本在语义层面的匹配程度。在本研究中,进行相似度计算之前,对特征向量进行了标准化处理,以消除由于向量长度不同而带来的潜在偏差。

  通过这种方式,我们能够定量评估特定文本描述与一组图像之间的匹配程度,这对于多模态数据分析、内容检索、以及自动化标注等应用领域具有重要的实际意义。这些分析结果不仅展示了CLIP模型在桥接视觉与语言之间差异方面的强大能力,也为未来的多模态研究和应用提供了重要的技术基础。

在这里插入图片描述

三、完整代码

from ultralytics import YOLO
import os
from PIL import Image, ImageDraw, ImageFont
import numpy as np
import torch
import matplotlib.pyplot as plt
import clip

# Load a pretrained YOLOv8s model
model = YOLO('yolov8s.pt')

# Load an image with PIL
original_image = Image.open('img/img1.jpg')

# Run inference on an image
results = model(original_image)

# Create a copy of the original image to draw bounding boxes
draw_image = original_image.copy()
draw = ImageDraw.Draw(draw_image)

# 类别映射
class_names = {
    0: "person", 1: "bicycle", 2: "car", 3: "motorcycle", 4: "airplane",
    5: "bus", 6: "train", 7: "truck", 8: "boat", 9: "traffic light",
    10: "fire hydrant", 11: "stop sign", 12: "parking meter", 13: "bench",
    14: "bird", 15: "cat", 16: "dog", 17: "horse", 18: "sheep", 19: "cow",
    20: "elephant", 21: "bear", 22: "zebra", 23: "giraffe", 24: "backpack",
    25: "umbrella", 26: "handbag", 27: "tie", 28: "suitcase", 29: "frisbee",
    30: "skis", 31: "snowboard", 32: "sports ball", 33: "kite", 34: "baseball bat",
    35: "baseball glove", 36: "skateboard", 37: "surfboard", 38: "tennis racket",
    39: "bottle", 40: "wine glass", 41: "cup", 42: "fork", 43: "knife",
    44: "spoon", 45: "bowl", 46: "banana", 47: "apple", 48: "sandwich",
    49: "orange", 50: "broccoli", 51: "carrot", 52: "hot dog", 53: "pizza",
    54: "donut", 55: "cake", 56: "chair", 57: "couch", 58: "potted plant",
    59: "bed", 60: "dining table", 61: "toilet", 62: "tv", 63: "laptop",
    64: "mouse", 65: "remote", 66: "keyboard", 67: "cell phone", 68: "microwave",
    69: "oven", 70: "toaster", 71: "sink", 72: "refrigerator", 73: "book",
    74: "clock", 75: "vase", 76: "scissors", 77: "teddy bear", 78: "hair drier",
    79: "toothbrush"
}

# Process results list
for result in results:
    boxes = result.boxes  # Boxes object for bbox outputs
    cls = boxes.cls
    conf = boxes.conf
    xyxyn = boxes.xyxyn

    # Convert tensor to numpy array and move data to CPU
    cls_numpy = cls.cpu().numpy()
    conf_numpy = conf.cpu().numpy()
    xyxyn_numpy = xyxyn.cpu().numpy()

    # Iterate over each detection
    for i in range(len(cls_numpy)):
        # Convert normalized coordinates to image coordinates
        box = xyxyn_numpy[i]
        xmin, ymin, xmax, ymax = box[0] * original_image.width, box[1] * original_image.height, box[2] * original_image.width, box[3] * original_image.height

        # Draw the bounding box
        draw.rectangle([(xmin, ymin), (xmax, ymax)], outline="red", width=2)

        # Get class label from cls number using the mapping
        class_label = class_names.get(int(cls_numpy[i]), 'Unknown')

        # Prepare text with class and confidence
        label = f'{class_label}: {conf_numpy[i]:.2f}'

        # Draw the class and confidence text
        draw.text((xmin, ymin), label, fill="white")

# # Save the annotated image
draw_image.save('annotated_image/annotated_img1.png')


# 定义一个函数来裁剪图像
def crop_image(original_image, box):
    x1, y1, x2, y2 = map(int, box)
    return original_image.crop((x1, y1, x2, y2))


# 创建一个目录来保存裁剪的图像,如果该目录不存在的话
os.makedirs('cropped_images', exist_ok=True)

# Process results list
for result in results:
    boxes = result.boxes  # Boxes object for bbox outputs
    cls = boxes.cls
    conf = boxes.conf
    xyxyn = boxes.xyxyn

    # Convert tensor to numpy array and move data to CPU
    cls_numpy = cls.cpu().numpy()
    conf_numpy = conf.cpu().numpy()
    xyxyn_numpy = xyxyn.cpu().numpy()

    # Iterate over each detection
    for i in range(len(cls_numpy)):
        # Convert normalized coordinates to image coordinates
        box = xyxyn_numpy[i]
        xmin, ymin, xmax, ymax = box[0] * original_image.width, box[1] * original_image.height, box[
            2] * original_image.width, box[3] * original_image.height

        # Draw the bounding box
        draw.rectangle([(xmin, ymin), (xmax, ymax)], outline="red", width=2)

        # Get class label from cls number using the mapping
        class_label = class_names.get(int(cls_numpy[i]), 'Unknown')

        # Prepare text with class and confidence
        label = f'{class_label}: {conf_numpy[i]:.2f}'

        # Draw the class and confidence text
        draw.text((xmin, ymin), label, fill="white")

        # Crop the image around the bounding box and save it
        cropped_img = crop_image(original_image, (xmin, ymin, xmax, ymax))
        cropped_img_path = os.path.join('cropped_images', f'{class_label}_{i}_{conf_numpy[i]:.2f}.jpg')
        cropped_img.save(cropped_img_path)

# Load the CLIP model
model, preprocess = clip.load("ViT-B/32", device='cuda')
model.eval()

# Prepare your images and texts
your_image_folder = "cropped_images"  # Change to the folder where you stored cropped images
your_texts = ["Drink water"]  # Replace with your list of texts

images = []
for filename in os.listdir(your_image_folder):
    if filename.endswith(".png") or filename.endswith(".jpg"):
        path = os.path.join(your_image_folder, filename)
        image = Image.open(path).convert("RGB")
        images.append(preprocess(image))

# Image and text preprocessing
image_input = torch.tensor(np.stack(images)).cuda()
text_tokens = clip.tokenize(your_texts).cuda()

# Compute features
with torch.no_grad():
    image_features = model.encode_image(image_input).float()
    text_features = model.encode_text(text_tokens).float()

# Normalize the features
image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)

print('image_features:', image_features)
print('text_features:', text_features)

print('image_features_shape:', image_features.shape)
print('text_features_shape:', text_features.shape)

# Calculate similarity
similarity = (text_features.cpu().numpy() @ image_features.cpu().numpy().T)

# Print similarity scores
print('Similarity:', similarity)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第四届微调——炼丹

学习地址:Tutorial/xtuner/README.md at main InternLM/Tutorial GitHub 笔记 微调是一种在已有的预训练模型基础上,通过使用新的数据对模型进行进一步优化和调整的技术手段。它的目的是使模型能够更好地适应特定的应用场景和任务需求,进一…

IDEA切换分支

方法一 1、选择要切换分支的module 2、右键,选择git 3、再点击branches 4、可以看到当前module的本地分支(local Branches)及远程分支(Remote Branches)列表。点击你要切换到的分支,Checkout即可。 方法二 1、点击…

MFC编程之设计美丽的对话框

目录 写在前面: Part 1:美美的设计一下计算器的布局 1.描述文字: ​编辑 2.ID: Part 2:美美熟悉一下计算器的工作流程 Part 3:美美设计一下控件功能 1.edit control: 2.相关变量初始化&…

Copilot for Microsoft 365 扩充新增 16 种语言

最近,微软公司发布公告,进一步扩大 Copilot for Microsoft 365 语言支持,新增 16 种,支持的语言总数达到 25 种。 新支持的语言如下: 阿拉伯语 捷克语 丹麦语 荷兰语 芬兰语 希伯来语 匈牙利语 韩语 挪威语&am…

Java面试之分布式篇

分布式锁的实现方案 (1)用数据库实现分布式锁比较简单,就是创建一张锁表,数据库对字段作唯一性约束。加锁的时候,在锁表中增加一条记录即可;释放锁的时候删除锁记录就行。如果有并发请求同时提交到数据库&…

二分判定+选插冒排序+归并快速堆希尔+计数排序

二分力扣题 一&#xff1a;搜索二维矩阵 74. 搜索二维矩阵 按照题意&#xff1a;直接利用二维数组转换成一维数组进行求解 方法一&#xff1a;普通等于的二分查找 class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {t…

Shell编程之循环语甸与函数

for 遍历循环 1&#xff09;for 变量 in 取值列表 for i in $(seq 1 10) do 命令序列 .... done 2&#xff09;for ((变量初始值; 变量范围; 变量的迭代方式)) for ((i1; i<10; i)) do 命令序列 .... done IFS for循环取值列表分隔符 set | grep IFS …

SSH常用功能介绍-高级功能

一、介绍 SSH&#xff08;Secure Shell&#xff09;是一种用于远程登录和执行命令的网络协议&#xff0c;它提供了加密的连接&#xff0c;保证了数据的安全性。除了基本的远程登录功能外&#xff0c;SSH还提供了许多高级功能&#xff0c;以下是一些常用的高级功能介绍&#xf…

Redis集群安装

将Redis安装包分别上传到3个文件夹&#xff0c;并解压缩 #编译并指定安装目录 cd /root/usr/local/redis-cluster/redis-7001/redis-6.2.6/ make make PREFIX/root/usr/local/redis-cluster/redis-7001 install # cd /root/usr/local/redis-cluster/redis-7002/redis-6.2.6/ m…

FreeRTOS二值信号量

目录 一、信号量的概念 1、信号量的基本概念 2、信号量的分类 二、二值信号量简介 三、二值信号量相关API 1、创建二值信号量 2、释放二值信号量 3、获取二值信号量 四、二值信号量实操 1、实验需求 2、CubeMX配置 3、代码实现 一、信号量的概念 1、信号量的基本概…

使用 CloudFlare 后如何才能不影响搜索引擎蜘蛛爬虫

今天,明月给大家再次详细讲解一下,明月在使用 CloudFlare 后如何才能不影响搜索引擎蜘蛛爬虫对站点的抓取,因为这是很多首次使用 CloudFlare 的站长们容易忽略和触犯的问题,并不是 CloudFlare 不友好,而是 CloudFlare 的防火墙(WAF)实在是太给力。其实在【CloudFlare 如…

IDEA及Maven配置代理及Maven中央仓库配置详解

一、配置代理 首先&#xff0c;需要本地开启代理入口&#xff0c;如图。 这个跟你使用代理软件有关。像我使用的是qv2ray。 其次&#xff0c;idea配置代理&#xff0c;如图。 1.1 idea配置代理 打开Settings&#xff0c;如图 1.2 maven配置代理 maven配置代理&#xff0c;修…

2024湖南理工学院程序设计竞赛(同步赛) G. 区间递减(思维题 分类讨论 ST表)

题目 https://ac.nowcoder.com/acm/contest/82672/G 思路来源 出题人 涼風青葉7代码 题解 注意到三种情况即可&#xff0c; 第一种情况&#xff0c;10 9 8 1 2&#xff0c;保留1 第二种情况&#xff0c;6 5 10 9 4 4&#xff0c;保留5 4 4 第三种情况&#xff0c;6 5 4&…

基于Springboot的校园疫情防控管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园疫情防控管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系…

Python 整数类型(int)详解:无限范围与多种进制

引言 在编程中&#xff0c;整数是最基本的数据类型之一。不同编程语言对整数的处理方式各不相同&#xff0c;这往往影响到程序的性能和开发者的选择。本文将深入探讨 Python 中的整数类型&#xff08;int&#xff09;&#xff0c;其独特的处理方式&#xff0c;以及它在日常编程…

【数据结构】环状链表OJ题

✨✨✨专栏&#xff1a;数据结构 &#x1f9d1;‍&#x1f393;个人主页&#xff1a;SWsunlight 一、OJ 环形链表&#xff1a; 快慢指针即可解决问题: 2情况&#xff1a; 快指针走到结尾&#xff08;不是环&#xff09;快指针和尾指针相遇&#xff08;是环的&#xff09; …

C语言——文件缓冲区

一、用户缓冲区和系统缓冲区 缓冲区的概念确实可以分为多个层次&#xff0c;其中最常见的两个层次是用户缓冲区和系统缓冲区。 这里的用户缓冲区和系统缓冲区都包括输入输出缓冲区。 1、用户缓冲区&#xff08;User-space Buffer&#xff09; 用户缓冲区是指由用户程序&…

09.zabbix自定义模块并使用

zabbix自定义模块并使用 根据tcp的11中状态获取值&#xff0c;进行批量配置监控项 [rootyunlong66 ~]# cat /etc/zabbix/zabbix_agentd.d/tcp.conf UserParameterESTABLISHED,netstat -antp |grep -c ESTABLISHED UserParameterSYN_SENT,netstat -antp |grep -c SYN_SENT Use…

免费思维13招之七:空间型思维

免费思维13招之七:空间型思维 本篇给你带来的是空间型思维。 空间型思维,具体分为内部空间型思维和外部空间型思维。 什么叫内部空间型思维呢? 内部空间型就是充分利用现有空间或资源为社会提供免费服务,积累人气,增加流量,从而带动消费。 为什么你生意不好?为什么你…

银河麒麟服务器操作系统扩展磁盘容量方法(非LVM)

此方法的使用场景为&#xff1a;对普通的分区扩容&#xff0c;分区格式为xfs&#xff0c;不适用于lvm逻辑卷的扩容。 注意&#xff1a;扩展磁盘空间的操作风险较高&#xff0c;最好先做好备份&#xff0c;或在实验环境下操作成功后&#xff0c;再对目标系统进行扩容操作&#…