视觉定位(Visual Grounding,后简称 Grounding)是根据对自然语言的任务要求,在图片中找到对应的目标,并返回目标的坐标,需要模型具备视觉理解以及自然语言理解的能力。
和目标检测最大的区别在于,输入多了自然语言信息,在对物体进行定位时需要理解自然语言的信息。使用上更加灵活交互更加自然。
输入 | 输出 | ||
---|---|---|---|
原始图片 | 提示词 | 模型输出坐标 | 按坐标绘图 |
框出中间狼卡通形象的头部的位置,输出 bounding box 的坐标 |
|
请参见视觉理解能力。
说明
您可以在飞书多维表格中进行 Grounding 测试、体验和使用,适合快速体验、简单场景,无需编码。
下面将基于示例代码,详细介绍grounding的使用流程。
首先导入必要的库,设置模型ID、图片路径和提示词等参数,并从环境变量中读取API密钥。
import os import base64 import cv2 from volcenginesdkarkruntime import Ark # 配置参数 DEFAULT_MODEL = "<MODEL>" # 替换为实际的模型ID IMAGE_PATH = "./ark_demo_img.png" PROMPT = "框出中间狼卡通形象的头部的位置,输出 bounding box 的坐标" BBOX_TAG_START = "<bbox>" BBOX_TAG_END = "</bbox>" # 读取API密钥 api_key = os.getenv("ARK_API_KEY") # 创建Ark客户端 client = Ark( api_key=api_key, )
读取本地图片文件,并将其转换为Base64字符串格式,以便通过API传输。
try: with open(IMAGE_PATH, "rb") as f: base64_image = base64.b64encode(f.read()).decode('utf-8')
将Base64编码的图片和文本提示词作为多模态输入,发送给grounding模型获取预测结果。
response = client.chat.completions.create( model=DEFAULT_MODEL, messages=[{ "role": "user", "content": [{ "type": "image_url", # 图片输入 "image_url": {"url": f"data:image/png;base64,{base64_image}"} }, { "type": "text", # 文本提示 "text": PROMPT }] }] ) bbox_content = response.choices[0].message.content
从模型返回的结果中提取边界框坐标,并验证其格式是否符合预期。
坐标格式为 <bbox>x_min y_min x_max y_max</bbox>
,其中(x_min
, y_min
)为方框左上角的坐标,(x_max
, y_max
)为方框右下角的坐标。
# 检查结果格式是否正确 if not (bbox_content.startswith(BBOX_TAG_START) and bbox_content.endswith(BBOX_TAG_END)): print("错误:边界框格式不正确,缺少标签包裹") exit(1) # 解析坐标值 try: coords_str = bbox_content[len(BBOX_TAG_START):-len(BBOX_TAG_END)] coords = list(map(int, coords_str.split())) if len(coords) != 4: # 验证坐标数量(xmin, ymin, xmax, ymax) raise ValueError("坐标数量不正确,需要4个数值") x_min, y_min, x_max, y_max = coords except ValueError as e: print(f"坐标解析失败: {str(e)}") exit(1)
转化坐标,x_min
, y_min
, x_max
, y_max
取值范围是 0-1000,是 归一化到 1000*1000 的比例坐标,即图片宽高分别等分为1000后,图片左上角为原点绘制坐标系,对应点的坐标位置,原理如下图所示。
根据图像实际尺寸缩放边界框坐标,将模型输出的相对坐标映射到绝对坐标,需进行计算,例如左上角坐标横轴绝对值是 x=x_min/1000*w
,w 是图片的实际宽度。
# 读取原图 image = cv2.imread(IMAGE_PATH) # 获取图像尺寸并缩放坐标(模型输出范围为0-1000) h, w = image.shape[:2] x_min_real = int(x_min * w / 1000) y_min_real = int(y_min * h / 1000) x_max_real = int(x_max * w / 1000) y_max_real = int(y_max * h / 1000) # 绘制红色边界框 cv2.rectangle(image, (x_min_real, y_min_real), (x_max_real, y_max_real), (0, 0, 255), 3) # 保存结果图片 output_path = os.path.splitext(IMAGE_PATH)[0] + "_with_bboxes.png" cv2.imwrite(output_path, image) print(f"成功保存标注图片: {output_path}")
配置并运行该示例代码,在代码路径下生成绘制后的图片预览。
场景 | 场景说明 | 触发条件 | 提示词 | 效果图 |
---|---|---|---|---|
带属性物体检测 | 需要定位图像中符合自然语言描述的特定属性的对象 | prompt里需包含关键词: |
| |
多目标检测 | 需要同时检测多个预定义类别的对象 | prompt里需包含关键词: | 请检测图像中所有属于 "plate(盘子)、photo(照片)、kid(小孩)、cup(杯子)" 类别的物体。对于每个物体,请提供其类别和边界框,格式为: | |
根据图像信息定位目标 | 根据目标的图像信息在另一张图中进行定位 | prompt里需包含关键词: |
| |
计算物体数量 | 需要统计特定对象的数量 | prompt里需包含关键词: |
| |
识别图像文本 | 需要提取图像中的文字内容及位置 | prompt里需包含关键词: | 标注图中的文字,格式为 | |
3D物体检测 | 检测图像中的3D立体格式的物体 | prompt里需包含关键词: |
|