【多模态实战】在本地计算机上使用视觉语言模型(VLM)进行目标检测【附源码】

发布于:2024-12-18 ⋅ 阅读:(34) ⋅ 点赞:(0)

《------往期经典推荐------》

一、AI应用软件开发实战专栏【链接】

项目名称 项目名称
1.【人脸识别与管理系统开发 2.【车牌识别与自动收费管理系统开发
3.【手势识别系统开发 4.【人脸面部活体检测系统开发
5.【图片风格快速迁移软件开发 6.【人脸表表情识别系统
7.【YOLOv8多目标识别与自动标注软件开发 8.【基于YOLOv8深度学习的行人跌倒检测系统
9.【基于YOLOv8深度学习的PCB板缺陷检测系统 10.【基于YOLOv8深度学习的生活垃圾分类目标检测系统
11.【基于YOLOv8深度学习的安全帽目标检测系统 12.【基于YOLOv8深度学习的120种犬类检测与识别系统
13.【基于YOLOv8深度学习的路面坑洞检测系统 14.【基于YOLOv8深度学习的火焰烟雾检测系统
15.【基于YOLOv8深度学习的钢材表面缺陷检测系统 16.【基于YOLOv8深度学习的舰船目标分类检测系统
17.【基于YOLOv8深度学习的西红柿成熟度检测系统 18.【基于YOLOv8深度学习的血细胞检测与计数系统
19.【基于YOLOv8深度学习的吸烟/抽烟行为检测系统 20.【基于YOLOv8深度学习的水稻害虫检测与识别系统
21.【基于YOLOv8深度学习的高精度车辆行人检测与计数系统 22.【基于YOLOv8深度学习的路面标志线检测与识别系统
23.【基于YOLOv8深度学习的智能小麦害虫检测识别系统 24.【基于YOLOv8深度学习的智能玉米害虫检测识别系统
25.【基于YOLOv8深度学习的200种鸟类智能检测与识别系统 26.【基于YOLOv8深度学习的45种交通标志智能检测与识别系统
27.【基于YOLOv8深度学习的人脸面部表情识别系统 28.【基于YOLOv8深度学习的苹果叶片病害智能诊断系统
29.【基于YOLOv8深度学习的智能肺炎诊断系统 30.【基于YOLOv8深度学习的葡萄簇目标检测系统
31.【基于YOLOv8深度学习的100种中草药智能识别系统 32.【基于YOLOv8深度学习的102种花卉智能识别系统
33.【基于YOLOv8深度学习的100种蝴蝶智能识别系统 34.【基于YOLOv8深度学习的水稻叶片病害智能诊断系统
35.【基于YOLOv8与ByteTrack的车辆行人多目标检测与追踪系统 36.【基于YOLOv8深度学习的智能草莓病害检测与分割系统
37.【基于YOLOv8深度学习的复杂场景下船舶目标检测系统 38.【基于YOLOv8深度学习的农作物幼苗与杂草检测系统
39.【基于YOLOv8深度学习的智能道路裂缝检测与分析系统 40.【基于YOLOv8深度学习的葡萄病害智能诊断与防治系统
41.【基于YOLOv8深度学习的遥感地理空间物体检测系统 42.【基于YOLOv8深度学习的无人机视角地面物体检测系统
43.【基于YOLOv8深度学习的木薯病害智能诊断与防治系统 44.【基于YOLOv8深度学习的野外火焰烟雾检测系统
45.【基于YOLOv8深度学习的脑肿瘤智能检测系统 46.【基于YOLOv8深度学习的玉米叶片病害智能诊断与防治系统
47.【基于YOLOv8深度学习的橙子病害智能诊断与防治系统 48.【基于深度学习的车辆检测追踪与流量计数系统
49.【基于深度学习的行人检测追踪与双向流量计数系统 50.【基于深度学习的反光衣检测与预警系统
51.【基于深度学习的危险区域人员闯入检测与报警系统 52.【基于深度学习的高密度人脸智能检测与统计系统
53.【基于深度学习的CT扫描图像肾结石智能检测系统 54.【基于深度学习的水果智能检测系统
55.【基于深度学习的水果质量好坏智能检测系统 56.【基于深度学习的蔬菜目标检测与识别系统
57.【基于深度学习的非机动车驾驶员头盔检测系统 58.【太基于深度学习的阳能电池板检测与分析系统
59.【基于深度学习的工业螺栓螺母检测 60.【基于深度学习的金属焊缝缺陷检测系统
61.【基于深度学习的链条缺陷检测与识别系统 62.【基于深度学习的交通信号灯检测识别
63.【基于深度学习的草莓成熟度检测与识别系统 64.【基于深度学习的水下海生物检测识别系统
65.【基于深度学习的道路交通事故检测识别系统 66.【基于深度学习的安检X光危险品检测与识别系统
67.【基于深度学习的农作物类别检测与识别系统 68.【基于深度学习的危险驾驶行为检测识别系统
69.【基于深度学习的维修工具检测识别系统 70.【基于深度学习的维修工具检测识别系统
71.【基于深度学习的建筑墙面损伤检测系统 72.【基于深度学习的煤矿传送带异物检测系统
73.【基于深度学习的老鼠智能检测系统

二、机器学习实战专栏【链接】,已更新31期,欢迎关注,持续更新中~~
三、深度学习【Pytorch】专栏【链接】
四、【Stable Diffusion绘画系列】专栏【链接】
五、YOLOv8改进专栏【链接】持续更新中~~
六、YOLO性能对比专栏【链接】,持续更新中~

《------正文------》

引言

img

本文主要介绍如何使用VLMs【视觉语言模型】进行对象检测。在过去,您必须训练自己的模型、收集训练数据才能进行指定类别的目标检测,但目前许多基础模型使您有一个坚实的基础来在它们之上进行微调,以获得一个可以检测对象并可以与对象进行交互的系统,同时可以通过自然语言进行交互。有数百种模型和潜在的应用程序可以使用对象检测,特别是随着小型语言模型的兴起,所以今天我们要尝试使用MLX的Qwen 2-VL-7 B-Instruct-8bit通过自然语言描述进行目标检测任务。

实现方式

我们将使用MLX-VLM,这是由Prince Canuma(Blaizzy)创建的一个包,他是一位充满激情的开发人员,专注于开发和移植大型语言模型以与MLX兼容,该框架为我们用户抽象了大量代码,以便用几行代码运行这些模型。

我们将使用下图来测试Qwen 2的目标检测能力。在本例中,我们将使用一个图像,其中有两辆采矿卡车或自卸卡车在矿场中运输矿石。这是一个用于采矿业的真实的应用程序的简单示例,因此您可以将此图像保存在一个名为images的新文件夹中,该文件夹位于代码的同一目录中!

img

现在让我们看一下下面显示的代码片段。首先,您可以从Hugging Face定义模型,框架将下载所有相关组件。这个过程非常简单,因为这个库还提供了多个实用程序(apply_chat_template)来将OpenAI的标准提示模板转换为小型VLM所需的模板。

对于这个例子,我们在一个用户消息中定义任务和响应格式,我们将要求模型识别所有对象并返回一个坐标列表,其中bboxes将是边界框的最小xy坐标和最大xy坐标。此外,我们还包含了对象名称,并要求模型以JSON对象的形式返回。

from mlx_vlm import load, apply_chat_template, generate
from mlx_vlm.utils import load_image


model, processor = load("mlx-community/Qwen2-VL-7B-Instruct-8bit")
config = model.config

image_path = "images/test.jpg"
image = load_image(image_path)

messages = [
    {
        "role": "user",
        "content": """detect all the objects in the image, return bounding boxes for all of them using the following format: [{
        "object": "object_name",
        "bboxes": [[xmin, ymin, xmax, ymax], [xmin, ymin, xmax, ymax], ...]
     }, ...]""",
    }
]
prompt = apply_chat_template(processor, config, messages)

output = generate(model, processor, image, prompt, max_tokens=1000, temperature=0.7)
print(output)

运行前面的代码后,您将收到一个JSON响应,其中正确识别了两辆卡车:

[{
    "object": "dump truck",
    "bboxes": [
        [100, 250, 380, 510]
    ]
}, {
    "object": "dump truck",
    "bboxes": [
        [550, 250, 830, 490]
    ]
}]

既然我们有了对象名称和边界框坐标,我们可以编写一个函数来将这些结果绘制在图像上。代码如下:

import json
import re
import matplotlib.pyplot as plt
from PIL import Image, ImageDraw, ImageFont

def draw_and_plot_boxes_from_json(json_data, image_path):
    """
    Parses the JSON data to extract bounding box coordinates,
    scales them according to the image size, draws the boxes on the image,
    and plots the image.

    Args:
        json_data (str or list): The JSON data as a string or already parsed list.
        image_path (str): The path to the image file on which boxes are to be drawn.
    """
    # If json_data is a string, parse it into a Python object
    if isinstance(json_data, str):
        # Strip leading/trailing whitespaces
        json_data = json_data.strip()
        # Remove code fences if present
        json_data = re.sub(r"^```json\s*", "", json_data)
        json_data = re.sub(r"```$", "", json_data)
        json_data = json_data.strip()
        try:
            data = json.loads(json_data)
        except json.JSONDecodeError as e:
            print("Failed to parse JSON data:", e)
            print("JSON data was:", repr(json_data))
            return
    else:
        data = json_data

    # Open the image
    try:
        img = Image.open(image_path)
    except FileNotFoundError:
        print(f"Image file not found at {image_path}. Please check the path.")
        return

    draw = ImageDraw.Draw(img)
    width, height = img.size
    # Change this part for Windows OS
    # ImageFont.FreeTypeFont(r"C:\Windows\Fonts\CONSOLA.ttf", size=25)
    font = ImageFont.truetype("/System/Library/Fonts/Menlo.ttc", size=25)  # Process and draw boxes
    for item in data:
        object_type = item.get("object", "unknown")
        for bbox in item.get("bboxes", []):
            x1, y1, x2, y2 = bbox
            # Scale down coordinates from a 1000x1000 grid to the actual image size
            x1 = x1 * width / 1000
            y1 = y1 * height / 1000
            x2 = x2 * width / 1000
            y2 = y2 * height / 1000
            # Draw the rectangle on the image
            draw.rectangle([(x1, y1), (x2, y2)], outline="blue", width=5)
            text_position = (x1, y1)
            draw.text(text_position, object_type, fill="red", font=font)

    # Plot the image using matplotlib
    plt.figure(figsize=(8, 8))
    plt.imshow(img)
    plt.axis("off")  # Hide axes ticks
    plt.show()

这是输出图像,边界框用正确的标签识别矿用卡车!

img

总结

这两年,随着视觉语言模型VLM正在快速发展,这为边缘设备开发这种应用类似的应用程序提供了无限可能。


在这里插入图片描述

好了,这篇文章就介绍到这里,喜欢的小伙伴感谢给点个赞和关注,更多精彩内容持续更新~~
关于本篇文章大家有任何建议或意见,欢迎在评论区留言交流!