首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

  • 24-12-06 00:05
  • 4360
  • 13995
juejin.cn

项目概述

一般检测图片上的物体我们会选用OpenCV、YOLO之类解决方案,但是他们都需要在本机安装很多东西,这里讲解如何使用AI API检测图片上的物体,这样基本可以0配置就实现该功能。另外,利用了大模型的特性,我们可以追加自然语言对识别结果进行限定。

Google Geimini 1.5 Pro多模态功能,不仅能检测图片上的物体,还能输出物体的边框坐标,这样理论上来说你可以在输入的图片上画上框和标注目标内容,很实用的功能。

注意提示词里面要限制输出的格式是JSON这样的方便解析的格式,例如:

javascript
代码解读
复制代码
检测图片上的物体,将边界框作为 JSON 数组返回,数组的名称为对象名称及其边界框 [ymin, xmin, ymax, xmax]。例如 'name_1': [ymin, xmin, ymax, xmax],只返回JSON格式,一定不要使用Markdown格式

可以直接调用Google Geimini 1.5 Pro的API实现,输入如上的题词,会得到这样的结果,然后自己在图片上画框即可

json
代码解读
复制代码
{'tiger': [121, 52, 852, 769], 'man': [164, 681, 821, 934]}

image.png

有网友已经做了开源项目:AlexZhangji/bonding_w_geimini: experiments with different llms (github.com),上传图片就可以显示检测结果,但是需要自备 Gemini 的 Api Key。

本文只是对该项目做了简化,以及题词的优化。

代码实现

  • 自备 Gemini 的 Api Key。
  • 网络要能访问 Gemini

这里我们可以对检测物体追加自然语言的要求,比如: “仅识别图中的大型车辆”

物体检测2.jpg

代码运行后可以看到大模型准确的识别了我们的意图

如果没有追加限定条件会返回

json
代码解读
复制代码
{'car_1': [573, 64, 791, 253], 'car_2': [605, 233, 722, 322], 'car_3': [622, 307, 696, 368], 'truck_1': [506, 368, 714, 554], 'truck_2': [523, 453, 728, 567], 'car_4': [622, 351, 685, 401]}

追加限定条件 “仅识别图中的大型车辆” 会返回

json
代码解读
复制代码
{'Truck_1': [515, 371, 732, 467], 'Truck_2': [531, 460, 725, 566]}

image-20241014164721068.png

安装依赖

代码解读
复制代码
pip install Pillow google-generativeai

配置文件config/gemini.config.json

json
代码解读
复制代码
{    "api_key": "" }

源代码

python
代码解读
复制代码
import json from PIL import Image, ImageDraw, ImageFont import google.generativeai as genai import random import os from google.api_core.exceptions import GoogleAPIError ​ ​ def resize_image(image, max_size=800):    """   调整图像大小,保持纵横比。如果任何一个维度超过 max_size,则将其缩小。   """    width, height = image.size    if width > height:        if width > max_size:            height = int((height * max_size) / width)            width = max_size    else:        if height > max_size:            width = int((width * max_size) / height)            height = max_size    return image.resize((width, height)) ​ ​ def generate_random_color():    """   生成十六进制格式的随机颜色。   """    return "#{:06x}".format(random.randint(0, 0xFFFFFF)) ​ ​ def get_font(size=20):    """   获取用于绘制文本的字体对象。尝试加载 NotoSansCJK-Regular.ttc。   如果不可用,则回退到默认字体。   """    font_files = ["NotoSansCJK-Regular.ttc"] ​    for font_file in font_files:        if os.path.exists(font_file):            try:                return ImageFont.truetype(font_file, size)            except IOError:                continue ​    return ImageFont.load_default() ​ ​ def draw_text_with_outline(draw, text, position, font, text_color, outline_color):    """   在图像上绘制带有轮廓的文本。   """    x, y = position    # 绘制轮廓    draw.text((x - 1, y - 1), text, font=font, fill=outline_color)    draw.text((x + 1, y - 1), text, font=font, fill=outline_color)    draw.text((x - 1, y + 1), text, font=font, fill=outline_color)    draw.text((x + 1, y + 1), text, font=font, fill=outline_color)    # 绘制文本    draw.text(position, text, font=font, fill=text_color) ​ ​ def draw_bounding_boxes(image, bboxes):    """   使用 bboxes 字典中提供的坐标在图像上绘制边界框。   """    draw = ImageDraw.Draw(image)    width, height = image.size ​    font = get_font(20) ​    for label, bbox in bboxes.items():        color = generate_random_color()        ymin, xmin, ymax, xmax = [            coord / 1000 * dim            for coord, dim in zip(bbox, [height, width, height, width])       ] ​        draw.rectangle([xmin, ymin, xmax, ymax], outline=color, width=3) ​        # 计算标签所需的区域并添加填充        label_bbox = font.getbbox(label)        label_width = label_bbox[2] - label_bbox[0] + 10  # 添加填充        label_height = label_bbox[3] - label_bbox[1] + 10  # 添加填充 ​        if xmax - xmin < label_width:            xmax = xmin + label_width        if ymax - ymin < label_height:            ymax = ymin + label_height ​        draw.rectangle(           [xmin, ymin, xmin + label_width, ymin + label_height], fill=color       )        draw_text_with_outline(            draw,            label,           (xmin + 5, ymin + 5),            font,            text_color="white",            outline_color="black",       )  # 为白色文本添加黑色轮廓    return image ​ ​ def extract_bounding_boxes(text):    """   从给定的文本中提取边界框,该文本应为 JSON 格式。   """    try:        bboxes = json.loads(text)        return bboxes    except json.JSONDecodeError:        import re ​        pattern = r'"([^"]+)":\s*[(\d+),\s*(\d+),\s*(\d+),\s*(\d+)]'        matches = re.findall(pattern, text)        return {label: list(map(int, coords)) for label, *coords in matches} ​ ​ def main():    api_key = ""    with open("./config/gemini.config.json", "r") as f:        config = json.load(f)        api_key = config.get("api_key")    # 定义发送给 Google Gemini 的提示,要求其检测图像中的物体并以 JSON 格式返回边界框。    prompt = "检测图片上的物体,将边界框作为 JSON 数组返回,数组的名称为对象名称及其边界框 [ymin, xmin, ymax, xmax]。例如 'name_1': [ymin, xmin, ymax, xmax],只返回JSON格式,一定不要使用Markdown格式。"    # 追加自然语言要求    prompt += "\n仅识别图中的大型车辆" ​    # 打开要进行物体检测的图像。    original_image = Image.open("./data/物体检测2.jpg") ​    # 调整图像大小以加快处理速度。    resized_image = resize_image(original_image)    # 配置 Google Gemini API 密钥。    genai.configure(api_key=api_key)    # 选择要使用的 Google Gemini 模型。    model = genai.GenerativeModel("gemini-1.5-pro-exp-0827") ​    try:        # 将提示和调整大小后的图像发送到 Google Gemini API。        response = model.generate_content([prompt, resized_image])    except GoogleAPIError:        return ​    # 从 Google Gemini API 的响应中提取边界框。    bboxes = extract_bounding_boxes(response.text)    print(bboxes)    # 如果检测到任何边界框,则在图像上绘制它们并显示图像。    if bboxes:        image_with_boxes = draw_bounding_boxes(resized_image.copy(), bboxes)        image_with_boxes.show() ​ ​ if __name__ == "__main__":    main() ​
注:本文转载自juejin.cn的lgc653的文章"https://juejin.cn/post/7425136905469116442"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top