利用 QVQ 模型构建通用图像目标检测工具
随着人工智能视觉技术的飞速发展,目标检测已成为众多应用的核心,无论是工业自动化、安防监控,还是日常生活的图像分析。大型视觉推理模型,如 QVQ,凭借其强大的理解能力,为实现灵活多变的目标检测任务提供了新的可能。本文将介绍一个简单的 Python 脚本,演示如何利用 QVQ 模型(通过兼容 OpenAI API 的接口,例如阿里云的灵骏智验 - DashScope)来实现对图像中特定目标的自动检测与
随着人工智能视觉技术的飞速发展,目标检测已成为众多应用的核心,无论是工业自动化、安防监控,还是日常生活的图像分析。大型视觉推理模型,如 QVQ,凭借其强大的理解能力,为实现灵活多变的目标检测任务提供了新的可能。
本文将介绍一个简单的 Python 脚本,演示如何利用 QVQ 模型(通过兼容 OpenAI API 的接口,例如阿里云的灵骏智验 - DashScope)来实现对图像中特定目标的自动检测与分类,并将结果结构化输出。与传统的固定类别目标检测模型不同,借助 QVQ 模型的强大泛化能力,我们可以通过调整提示文本(Prompt),实现对各种“日常业务相关”对象的检测,而无需重新训练模型。
脚本功能概览
这个 Python 脚本主要完成以下任务:
- 扫描指定文件夹下的图片文件。
- 将每张图片编码为 Base64 字符串。
- 构建一个包含图片和描述检测任务的文本提示的消息体。
- 调用基于 QVQ 模型构建的 AI 服务 API。
- 处理模型的流式响应,分离模型的思考过程和最终的检测结果(JSON 格式)。
- 将思考过程和检测结果保存到对应的文本文件中。
核心代码与讲解
下面是实现上述功能的 Python 代码。请注意,与原始代码不同,我们在处理 API 凭证时采用了更安全的方式,避免了将密钥硬编码在脚本中。
import glob
import os
import base64
from openai import OpenAI # 需要安装 openai 库: pip install openai
import json # 引入 json 库用于可能的后续处理或验证
# --- 安全配置提醒 ---
# 为了保护您的 API 密钥,请勿将其硬编码在代码中。
# 推荐使用环境变量来存储敏感信息。
# 在运行脚本前,请设置以下环境变量:
# export QVQ_API_KEY='您的API密钥'
# export QVQ_BASE_URL='兼容OpenAI API的端点URL (如: https://dashscope.aliyuncs.com/compatible-mode/v1)'
#
# Windows 用户可以使用 set 命令 (cmd) 或 $env: (PowerShell)。
API_KEY = os.getenv("QVQ_API_KEY")
BASE_URL = os.getenv("QVQ_BASE_URL")
if not API_KEY or not BASE_URL:
print("错误:API 密钥 (QVQ_API_KEY) 和基础 URL (QVQ_BASE_URL) 必须设置为环境变量。")
print("请在运行脚本前设置相应的环境变量。")
exit(1)
# --- 辅助函数:图片编码 ---
def encode_image(image_path):
"""将图片文件编码为 Base64 字符串"""
try:
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode("utf-8")
except Exception as e:
print(f"错误:无法编码图片文件 {image_path}: {e}")
return None
# --- 主要处理逻辑 ---
# 使用 glob 查找指定目录下符合条件的图片文件 (例如: best_output_folder 下任意子目录的 jpg 文件)
output_key_frames = glob.glob("best_output_folder/*/*.jpg")
# 初始化 OpenAI 客户端
# 注意:即使对接的是兼容 OpenAI API 的第三方服务,通常也可以使用 openai 库,
# 但需要通过 base_url 参数指定服务地址。
try:
client = OpenAI(
api_key=API_KEY,
base_url=BASE_URL
)
except Exception as e:
print(f"错误:初始化 OpenAI 客户端失败:{e}")
print("请检查您的 BASE_URL 和 API_KEY 是否正确,并确保 openai 库已安装。")
exit(1)
print(f"找到 {len(output_key_frames)} 张图片待处理。")
print("脚本将调用 QVQ 模型进行目标检测,并通过兼容 API 进行通信。")
# 遍历找到的图片文件
for output_key_frame in output_key_frames:
print(f"\n正在处理图片:{output_key_frame}")
base64_image = encode_image(output_key_frame)
if base64_image is None:
print(f"跳过图片 {output_key_frame} 由于编码失败。")
continue # 如果图片编码失败,跳过当前文件
reasoning_content = ""
answer_content = ""
is_answering = False # 标志,用于判断何时开始接收最终的 JSON 回复内容
# --- 定义检测任务的 Prompt ---
# 这是核心部分,通过修改这里的文本来指定要检测的目标类型。
# 我们将原始的“飞机内外部标识”替换为更通用的描述。
# IMPORTANT: 请根据你的实际“日常业务”需求,将“其他日常业务相关标识或对象”
# 替换为更具体的描述,例如:“图像中所有的交通标志”、“商品包装上的标签”等。
detection_prompt = """你需要完成目标检测任务,检测图像中所有的其他日常业务相关标识或对象,并按照以下分类:
0: 清晰 (Clear)
1: 模糊 (Blurred)(由于拍摄原因导致模糊)
2: 褪色(由于标识本身老化导致模糊)
3: 缺失 (Missing)(标识不完整)
4: 遮盖 (Covered)
要求返回 **严格的 JSON 格式**,结构如下:
[
{"bbox_2d": [中心x, 中心y, 宽w, 高h], "label": "类别"},
...
]
注意事项:
- bbox_2d四个数值是归一化到0-1之间的小数。
- label字段的值需要带上编号和名称,如"0: 清晰 (Clear)"。
- 只返回JSON,不要添加任何额外文字解释或其他内容。
示例参考:
[
{"bbox_2d": [0.037932, 0.489878, 0.075865, 0.024334], "label": "0: 清晰 (Clear)"},
{"bbox_2d": [0.485701, 0.402788, 0.220856, 0.099898], "label": "2: 褪色"},
{"bbox_2d": [0.624589, 0.654133, 0.209472, 0.096696], "label": "2: 褪色"},
{"bbox_2d": [0.814139, 0.649010, 0.137750, 0.055712], "label": "2: 褪色"}
]"""
# --- 调用模型 API ---
try:
completion = client.chat.completions.create(
model="qvq-max", # 指定使用的 QVQ 模型版本
messages=[
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {"url": f"data:image/png;base64,{base64_image}"}, # 使用 data URL 格式发送 Base64 图片
},
{"type": "text", "text": detection_prompt} # 发送包含检测任务的文本提示
],
}
],
stream=True, # 启用流式处理,可以实时接收模型响应
)
print("\n" + "=" * 20 + "模型思考过程 (Reasoning)" + "=" * 20 + "\n")
# --- 处理流式响应 ---
for chunk in completion:
if not chunk.choices:
# 处理 chunk 中可能包含的 usage 信息或错误
if hasattr(chunk, 'usage') and chunk.usage:
print("\nUsage Info:", chunk.usage)
else:
print("\n接收到空或异常 chunk:", chunk)
continue # 跳过当前 chunk
delta = chunk.choices[0].delta
# 根据 delta 对象中的属性来判断是思考过程还是实际内容
# 注意:不同的 API 实现可能对 'reasoning_content' 或其他属性的支持有所不同
if hasattr(delta, 'reasoning_content') and delta.reasoning_content is not None:
# 打印并累积思考过程
print(delta.reasoning_content, end='', flush=True)
reasoning_content += delta.reasoning_content
elif delta.content is not None: # 这是模型的实际回复内容(期望是 JSON)
if delta.content != "" and is_answering is False:
# 第一次接收到实际内容时打印分隔符
print("\n" + "=" * 20 + "检测结果 (Answer JSON)" + "=" * 20 + "\n")
is_answering = True
# 打印并累积最终回复内容
print(delta.content, end='', flush=True)
answer_content += delta.content
# --- 保存输出结果 ---
# 根据输入图片路径生成输出文件路径
base_name = os.path.splitext(os.path.basename(output_key_frame))[0]
second_last_dir = os.path.basename(os.path.dirname(output_key_frame))
save_dir = os.path.join("best_output_folder_texts", second_last_dir)
os.makedirs(save_dir, exist_ok=True) # 创建保存目录,如果不存在则创建
# 保存思考过程
reasoning_file_path = os.path.join(save_dir, f"{base_name}_reasoning.txt")
with open(reasoning_file_path, "w", encoding="utf-8") as f:
f.write(reasoning_content)
# 保存检测结果 (JSON)
answer_file_path = os.path.join(save_dir, f"{base_name}_answer.txt")
with open(answer_file_path, "w", encoding="utf-8") as f:
# 可选:尝试验证 JSON 格式是否正确
try:
json.loads(answer_content)
with open(answer_file_path, "w", encoding="utf-8") as f:
f.write(answer_content)
except json.JSONDecodeError:
print(f"\n警告:图片 {output_key_frame} 的回复内容不是有效的 JSON 格式。")
# 即使不是有效 JSON 也保存,便于排查问题
with open(answer_file_path, "w", encoding="utf-8") as f:
f.write("ERROR: Invalid JSON response\n" + answer_content)
print(f"\n保存完成:\n - 思考过程: {reasoning_file_path}\n - 检测结果: {answer_file_path}")
except Exception as e:
print(f"\n处理图片 {output_key_frame} 时发生错误:{e}")
# 可以在这里选择记录错误信息到文件或进行其他处理
print("\n所有图片处理完成。")
如何使用
- 安装依赖:
pip install openai - 准备图片: 将待检测的图片文件(例如
.jpg格式)放入一个按照best_output_folder/*/*.jpg结构组织的文件夹中。 - 设置环境变量: 在运行脚本的终端中设置
QVQ_API_KEY和QVQ_BASE_URL环境变量。这是确保 API 密钥安全的关键步骤。请替换示例中的占位符为您的实际密钥和端点 URL。- Linux/macOS Bash:
export QVQ_API_KEY='sk-your-key-here' export QVQ_BASE_URL='https://dashscope.aliyuncs.com/compatible-mode/v1' # 替换为您的实际兼容 API 端点 - Windows Command Prompt (cmd):
set QVQ_API_KEY=sk-your-key-here set QVQ_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1 # 替换为您的实际兼容 API 端点 - Windows PowerShell:
$env:QVQ_API_KEY='sk-your-key-here' $env:QVQ_BASE_URL='https://dashscope.aliyuncs.com/compatible-mode/v1' # 替换为您的实际兼容 API 端点
- Linux/macOS Bash:
- 修改 Prompt: 务必修改脚本中
detection_prompt变量的值, 将"其他日常业务相关标识或对象"替换为你实际想要检测的具体目标描述。Prompt 的清晰度和准确性直接影响模型的检测效果。 - 运行脚本:
(请将python your_script_name.pyyour_script_name.py替换为你保存脚本的文件名)
通过这个脚本,我们展示了如何利用 QVQ 这样强大的多模态模型,通过简单的 API 调用和灵活的文本提示,实现定制化的图像目标检测任务。这种方法避免了为每个新类别的对象单独训练模型的繁琐过程,极大地提高了开发效率和模型的应用范围。通过安全地管理 API 凭证并根据需求调整提示文本,你可以将这个框架轻松应用于各种“日常业务”中的图像分析场景。
更多推荐


所有评论(0)