万字长文讲解如何搭建用于开放目标检测的工作流
01
引言
传统上,计算机视觉任务(如图像分类、目标检测和语义分割)通常被视为闭集问题,模型只能识别训练时见过的类别。即使CNN深度学习推动了性能提升,但适应新领域或识别未见过的物体仍需重新训练或微调。
随着基于Transformer的架构(尤其是CLIP)的出现,这一局面发生了重大转变。CLIP通过在数亿张带标题的图片上联合训练文本和图像编码器,学习到了一个共享的图像-文本表征空间。由于两种模态存在于同一嵌入空间,用户可以用任意文本(如新类别标签或描述性短语)提示模型,CLIP能将其与相关视觉特征关联起来——即使训练时从未见过该物体或短语。
CLIP的图像-文本预训练实现了开放词汇检测与分割。DINO和OWL-ViT等模型无需重新训练即可定位"蓝色回收箱"或"涂鸦停止标志"等短语。后续研究进一步融合了感知与文本能力:多模态大模型(GPT-4V、Gemini、Claude-Sonnet)将类CLIP图像编码器与文本解码器结合,实现了多模态功能。
从固定类别的CV模型转向基于VLM的可适应系统,这一变革正推动自主框架的发展。开发者无需手动设计标签或重新训练,通过简单语言指令即可处理多样化任务。可以实时引导智能体检测训练数据之外的新物体、分割区域或解释训练数据之外的场景。这种方法摆脱了传统基于标签方法的限制,使视觉任务能够实时组合调整。
OpenAI发布的o3模型将这一范式实现为完全自主的视觉系统。o3不仅能直接生成检测框,还能自主调用外部工具:例如编写Python代码缩放/旋转图像或调整对比度、启动网络搜索获取上下文信息、将结果反馈至推理流程并迭代优化。这种能力标志着向真正自主的计算机视觉智能体迈出重要一步——在单次推理中整合感知、工具使用和迭代自检。
02
实现Agentic Object Detection
在本篇博文中,我们将阐述如何构建一个自主目标检测框架——通过结合开放词汇检测器与多模态大模型(VLMs)的校验修正能力,形成闭环优化系统。
,时长00:35
-
总体设计

本框架通过整合开放词汇目标检测器与视觉语言模型(VLM)的校验能力,构建端到端的主动化检测流程:
-
概念推理:用户上传图像及需求后,采用VLM(GPT-4o)解析关键物体概念。若请求已指明具体对象则直接提取,否则由VLM自主识别图像中显著物体。
-
初始检测:将提取的概念输入开放词汇检测器(Grounding DINO)生成初始边界框。
-
交互式标注:在图像上以箭头+数字标签标注检测结果,添加白色边框提升可视性。
-
查询修正:将标注图像、提取概念与原始请求输入VLM推理引擎(OpenAI o1),通过思维链推理识别错误分类或过度具体化标签(如"贵宾犬→犬类"、“板球手→人群”),优化类别抽象层级。
-
精炼检测:将优化后的概念列表反馈至检测器,对原图执行二次定位检测。
-
终筛过滤:更新后的检测结果经VLM(GPT-4o)进行思维链推理,比对用户原始意图过滤无关检测框。
-
输出交付:最终生成精准匹配用户需求的带验证标注图像。
-
验证机制与推理时计算
大语言模型和多模态模型可作为校验器,对主模型输出进行审查验证(主模型通常能力有限),从而提升结果质量。研究者还探索了推理时计算(test-time compute)方法——在不更新模型权重的前提下,通过多步思维链推理和自洽性采样等机制,为模型分配更多计算资源以实现"深度思考"。
本流程融合了这两大理念,在开放集初检后执行两轮VLM驱动的验证:
-
校验与抽象(步骤4):VLM对标注图像进行全量边界框审查,通过单次完整前向推理实现错误修正与概念抽象
-
精确定位(步骤5):基于修正概念执行二次检测,利用开放词汇模型在粗粒度分类的优势提升召回
-
最终过滤(步骤6):最终推理阶段通过跨模态比对确保检测结果与用户需求精确匹配,剔除仍不相关的检测框。
-
为何需要额外计算?
-
模型无关增益:验证仅发生在推理阶段,可随时替换新版检测器或推理模型,无需重新训练或额外数据收集,提升纯粹来自计算资源。
-
可解释性:思维链日志记录预测被拒原因,为开发者和利益相关者提供调试依据。
通过显式分配推理时计算资源进行验证修正,该流程将原始开放集检测升级为自主系统——无需收集新数据或重新训练模型,即可产出符合用户意图的高精度结果。
03
代码实现之目标检测Pipeline
为了实现该流程,我们首先着手开发一项功能,用于提取用户提供图像中的高级概念或物体对象。
-
VLM工具
为了通过API将图像发送至OpenAI的视觉语言模型(VLM),我们需要将其编码为base64字符串。为此我们实现了一个辅助函数:
import base64def encode_image(image_path):"""Encodes an image file into a base64-encoded string.Args:image_path (str): Path to the image file to be encoded.Returns:str: Base64-encoded string of the image content.None: If an error occurs during encoding.Raises:Exception: If the file cannot be opened or encoded."""try:with open(image_path, "rb") as image_file:return base64.b64encode(image_file.read()).decode("utf-8")except Exception as e:print(f"Error encoding image: {e}")return None
我们首先将VLMTool实现为OpenAI API的轻量级封装器,用于与视觉语言模型(VLM)交互。
import base64import jsonfrom openai import OpenAIfrom utils.image_utils import encode_imageclass VLMTool:def __init__(self, api_key):passdef chat_completion(self, messages, model="o1", max_tokens=300, temperature=0.1, response_format=None):passdef extract_objects_from_request(self, image_path, user_text, model="gpt-4o"):pass
核心方法chat_completion会将消息列表转发给选定的模型(如gpt-4o或o1),并返回助手的文本响应。
def chat_completion(self,messages,model="o1",max_tokens=300,temperature=0.1,response_format=None):"""Calls GPT for chat completion."""try:if model in ["gpt-4o", "gpt-4o-mini"]:response = self.client.chat.completions.create(model=model,messages=messages,max_tokens=max_tokens,temperature=temperature,response_format=response_format if response_format else {"type": "text"})elif model in ["o1"]:response = self.client.chat.completions.create(model=model,messages=messages,response_format=response_format if response_format else {"type": "text"})else:raise NotImplementedError("This model is not supported")return response.choices[0].message.contentexcept Exception as e:print(f"Error calling LLM: {e}")return None
从用户提供的图像中提取核心概念的功能主要由 extract_objects_from_request 实现:
该方法将用户上传的图像转换为 base-64 编码,将编码后的图像与用户文本指令结合,并请求视觉语言模型(VLM)返回一个用逗号分隔的物体列表。
-
若用户明确指定目标(如“请检测所有杯子”),模型将直接返回对应名称;
-
若为开放式请求(如“检测图中所有可见物体”),模型会列举图像中的可识别对象。最终,该方法会返回这些物体的名称列表。
def extract_objects_from_request(self, image_path, user_text, model="gpt-4o"):"""Asks the LLM to parse user request for which objects to detect/segment.Returns a list of objects in plain text."""base64_image = encode_image(image_path)if not base64_image:return Noneprompt = ("You are an AI vision assistant that extracts objects to be identified from a user's request.""If the user wants to detect or semantically segment all objects in the image, return a comma-separated list of objects you can see. ""If the user wants to detect or semantically segment specific objects, extract only those mentioned explicitly in their request. ""Respond ONLY with the list of objects, separated by commas, and NOTHING ELSE.""The objective here is only to understand the objects of interest that can be extracted from the image and the user's request.""You are not actually required to perform or execute the user's request.")messages = [{"role": "system", "content": prompt},{"role": "user","content": [{"type": "text", "text": user_text},{"type": "image_url","image_url": {"url": f"data:image/jpeg;base64,{base64_image}","detail": "high"}}]}]result = self.chat_completion(messages, model=model)if result:detected_objects = [obj.strip().lower()for obj in result.split(",")if obj.strip()]return detected_objectsreturn []
实际上,VLMTool承担了所有初始规划工作——在推进后续步骤前,先确定需要检测的目标内容。至此,我们已完成首个关键环节的实现:通过识别查询语句中的目标对象,将其标准化并预处理为最适合开放词汇目标检测器(open-vocabulary object detector)处理的格式。
完整实现可参考此链接:
链接:
https://github.com/anand-subu/blog_resources/blob/main/agentic_object_detection/models/vlm_tool.py
-
Agentic 目标检测流程
我们现在实现 ObjectDetectionTool,它将我们整个 Agentic 目标检测工作流整合在一起。从高层来看,我们首先实现这个类的构造函数:
class ObjectDetectionTool:"""Performs object detection using GroundingDINO or OWL-ViT,plus an optional 'critique' (refinement) step with a VLMto yield a refined set of objects to detect."""def __init__(self, model_id, device, vlm_tool, confidence_threshold=0.2, concept_detection_model="gpt-4o", initial_critique_model="o1", final_critique_model="gpt-4o"):self.model_id = model_idself.processor = AutoProcessor.from_pretrained(model_id)self.model = AutoModelForZeroShotObjectDetection.from_pretrained(model_id).to(device)self.device = deviceself.vlm_tool = vlm_tool # The LLMTool that can handle vision (GPT-4V) or similarself.confidence_threshold = confidence_thresholdself.concept_detection_model = concept_detection_modelself.initial_critique_model = initial_critique_modelself.final_critique_model = final_critique_model# We store bounding boxes for potential usage later (e.g., for SAM).self.last_detection_bboxes = []self.last_filtered_objects = []
此模块设置了视觉-语言处理的核心组件。它将检测器权重——无论是 Grounding-DINO 还是 OWL-ViT——加载到 CPU 或 GPU 上(在本博客的所有案例中,我们都使用 Grounding-DINO)。它初始化语言模型权重,存储共享的 VLMTool 实例以及用于初始和最终验证阶段的指定 LLM。它还配置边界框的置信度阈值,并分配缓存以存储最近的检测结果。
04
代码实现之运行目标检测器
接着j我们实现了一个方法_ run_detector,用于使用开词汇量目标检测器进行第一次前向传播。
def _run_detector(self, image_path, query_list):"""Low-level routine to run the detection model on `query_list`.Returns: (detected_objects_final, labeled_image_path)Where `detected_objects_final` = [(num, label, [x1,y1,x2,y2]), ...]."""from PIL import ImageFont# Format queries for the modelif INV_MODEL_TYPES[self.model_id] == "owlvit":formatted_queries = [f"An image of {q}" for q in query_list]elif INV_MODEL_TYPES[self.model_id] == "grounding_dino":formatted_queries = " ".join([f"{q}." for q in list(set(query_list))])else:raise NotImplementedError("Model not supported")# Load imageimg = Image.open(image_path).convert("RGB")inputs = self.processor(text=formatted_queries,images=img,return_tensors="pt",padding=True,truncation=True).to(self.device)self.model.eval()with torch.no_grad():outputs = self.model(**inputs)# Post-process bounding boxesif INV_MODEL_TYPES[self.model_id] == "grounding_dino":results = self.processor.post_process_grounded_object_detection(outputs,inputs.input_ids,box_threshold=0.4,text_threshold=0.3,target_sizes=[img.size[::-1]])boxes = results[0]["boxes"]scores = results[0]["scores"]labels = results[0]["labels"]elif INV_MODEL_TYPES[self.model_id] == "owlvit": # OWL-ViTlogits = torch.max(outputs["logits"][0], dim=-1)scores = torch.sigmoid(logits.values).cpu().numpy()labels = logits.indices.cpu().numpy()boxes = outputs["pred_boxes"][0].cpu().numpy()else:raise NotImplementedError("Model not supported")detected_objects_final = []idx = 1for score, box, label_idx in zip(scores, boxes, labels):if score < self.confidence_threshold:continuedetected_objects_final.append((idx, label_idx, box.tolist()))idx += 1# Draw numberslabeled_image_path = draw_arrows_and_numbers(image_path, detected_objects_final)return detected_objects_final, labeled_image_path
该流程首先将提示词适配到目标模型——OWL-ViT需要一个列表,例如[“一张猫的图片”],而DINO则偏好以句点分隔的字符串,如“cat. dog.”。接下来,在torch.no_grad()上下文中执行一次变换器的前向传播。得到的原始归一化边界框会被转换为像素坐标,并且任何低于置信度阈值的检测结果都会被舍弃。最后,将箭头和数字标签绘制在图片上,以便后续的语言模型可以通过如“框#3”这样的方式明确引用对象。我们还实现了一个实用函数,用于绘制箭头和边界框:
def draw_arrows_and_numbers(image_path, detected_objects):"""Draws arrows and numbers on an image to label detected objects.This function dynamically places numbers near the borders with arrows pointingfrom object centers to the borders. Arrows are dashed for clarity, and thenumbering avoids overlap when possible.Args:image_path (str): Path to the input image.detected_objects (list): List of tuples containing object information inthe format (number, object_name, bounding_box), where bounding_box is(x1, y1, x2, y2).Returns:str: Path to the saved labeled image ('labeled_objects_optimized.jpg').Note:- Arrows are drawn from object centers to the nearest border.- Numbers are displayed with semi-transparent backgrounds for readability."""img = cv2.imread(image_path)font = cv2.FONT_HERSHEY_SIMPLEXused_positions = []# Pad the image with a white bordertop, bottom, left, right = 50, 50, 50, 50img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=[255, 255, 255])height, width, _ = img.shapefor i, (num, obj, box) in enumerate(detected_objects):x1, y1, x2, y2 = map(int, box)cx, cy = (x1 + x2) // 2, (y1 + y2) // 2 # Center of the bounding box# Adjust coordinates for padded imagex1 += lefty1 += topx2 += lefty2 += topcx += leftcy += top# Determine arrow direction towards the nearest borderdistances = {'top': cy, 'bottom': height - cy, 'left': cx, 'right': width - cx}direction = min(distances, key=distances.get)if direction == 'top':arrow_end = (cx, top)text_position = (cx - 10, top - 10)elif direction == 'bottom':arrow_end = (cx, height - bottom)text_position = (cx - 10, height - 5)elif direction == 'left':arrow_end = (left, cy)text_position = (left - 30, cy + 5)else:arrow_end = (width - right, cy)text_position = (width - 30, cy + 5)# Draw the dashed arrow from the object center to the bordercolor = (0, 0, 0) # Black color for all arrowsline_type = cv2.LINE_4cv2.arrowedLine(img, (cx, cy), arrow_end, color, 2, tipLength=0.3)# Draw a semi-transparent rectangle behind the textoverlay = img.copy()cv2.rectangle(overlay, (text_position[0] - 5, text_position[1] - 20), (text_position[0] + 30, text_position[1] + 5), (0, 0, 0), -1)alpha = 0.5cv2.addWeighted(overlay, alpha, img, 1 - alpha, 0, img)# Draw the number at the border with black textcv2.putText(img, str(num), text_position, font, 0.8, color, 2)labeled_image_path = "labeled_objects_optimized.jpg"cv2.imwrite(labeled_image_path, img)return labeled_image_path
05
编号批处理
验证检测结果最直接的方法是将每个边界框视为独立任务。检测器运行后,系统会遍历生成的n个边界框,并对每个框执行以下流程:
-
截取区域:提取边界框定义的矩形区域,或在候选物体周围绘制边界框。
-
Base64编码:将截取的新图像编码为data:image/jpeg;base64,…格式字符串并发送。
-
构造专用提示词:编写嵌入图像的提示词,例如:“图像中的边界框是否包含杯子?回答‘是’或‘否’。”
-
发送至视觉语言模型(VLM):模型执行完整前向传播——解析提示词、解码图像并生成文本判断。
-
解析结果:若模型回答"否"则丢弃该框,否则保留。
该循环会持续至所有边界框检查完毕。在复杂场景中,检测器可能返回数十个边界框,验证器便需运行数十次。
此方法的弊端在于处理开销、成本和延迟。每次截取都会触发新的API调用、图像上传和模型前向传播。25次检测意味着25次调用,导致延迟和token/图像计费成本增加25倍。
编号箭头标注法通过将验证阶段转化为一次上下文丰富的VLM处理,规避了所有上述缺点。为每个检测结果标注带编号的箭头,再将合成图像交给语言模型,可从三个相互关联的方面获益——速度、成本和推理质量:
-
更快的处理与扩展能力
通过在单张图像上叠加箭头和编号,系统仅需发送一张图像和一个提示词,大幅降低验证成本和总处理时间。这相当于批处理机制——在高物体数量场景中,即使检测量增加,验证时间也能保持基本稳定。唯一边际成本是绘制额外箭头,与额外检测器或LLM调用相比可忽略不计。
-
确定性强、便于引用的ID
稳定编号的箭头作为贯穿流程的主键:LLM可直接声明"3号和6号框无效",代码能精准过滤这些整数,人类也能直观查看对应编号。若仅依赖文本描述(如"勺子下方的蓝色杯子"),则需面对脆弱的字符串匹配或易出错的启发式规则。数字ID实现了视觉代码与语言模型间的无损衔接。
-
更高效利用视觉token预算
VLM的分辨率预算有限(通常为单张图像加数千文本token)。箭头几乎不占用图像面积,既能保留原始细节,又为模型提供明确指向。
简言之,暴力截取循环虽简单,但计算效率和成本效益低下;而箭头批处理通过高效利用VLM的上下文窗口,实现了更快、更经济的处理。
06
查询优化与修正
系统会将当前检测结果与用户文本一并输入LLM,询问其概念是否过于狭窄。若确实如此,LLM会建议更宽泛的术语(如用"狗"替代"茶杯贵宾犬"),并以逗号分隔列表形式输出。这一步骤通过牺牲计算资源换取鲁棒性:仅当列表发生变化时才会触发额外LLM调用并重新运行检测器,刻意在验证器判定初始尝试不足时投入更多算力。
通用开放词汇检测器通常仅能识别数百种粗粒度类别(如"狗"、“汽车”、“花”),但用户常提出更细粒度的目标(如茶杯贵宾犬、镶钻细高跟鞋等)。当请求标签超出检测器能力范围时,模型可能返回空结果或一堆低置信度边界框。
在评估和完善阶段,LLM 会一次性接收三样东西:用户的原始文本、带箭头注释的图像,以及传递给检测器的确切概念列表。然后,它会进行推理:“检测器在这些标签下找到有意义的内容了吗?如果没有,这些标签是否过于具体?”一旦出现这种情况,LLM 就会故意将每个概念向上抽象到更高级的概念,例如:亚品种变成品种(茶杯贵宾犬 → 狗),复杂的颜色概念被剥离(亮红色复古跑车 → 汽车)。模型将这些更高级别的类别作为逗号分隔的字符串返回。
def _critique_and_refine_query(self, user_request, original_concepts, labeled_image_path, objects_detected, model="o1"):"""Asks the VLM/LLM: "We tried to detect <objects_detected> for the user request,but maybe we need a refined set of objects.Return a new list of objects or concepts to detect.""""base64_labeled_image = encode_image(labeled_image_path)# For clarity, let's pass the original user request and# the currently detected object list to the LLM.# The LLM can propose a refined set of objects to detect.refine_messages = [{"role": "system","content": """You are an AI system that refines detection queries.You are provided with the outputs from an object detection model, along with the user's request and the objects from the user's request that were extracted and provided to the object detection model.Your task is to analyze whether the object detector has extracted the results properly to the user's request and, if not, refine the queries by generalizing concepts where possible.Important guidelines:1. If the detection results are already good, no need to refine.- In that case, provide reasoning indicating no refinement was necessary and return the same list.2. If the detection results are poor or null, propose synonyms or more generic categories and explain why. Wherever possible, retain the singular version of the concept.3. Return your final answer as a JSON object with exactly two fields: "reasoning" and "refined_list".- "reasoning" is a short explanation of why you refined or didn't refine.- "refined_list" is a comma-separated list of object names that should be re-tried in detection.4. Output ONLY the JSON, and no other text.Below are some examples:EXAMPLE 1User's Request: Detect the teacup poodleOriginal concept: "Teacup poodle"Final output:{"reasoning": "The provided image does not have any detections for the concept of teacup poodle. The concept "teacup poodle" might be a very specific concept for the model to detect. This could be refined to a more higher-level and generic concept like 'Dog',"refined_list": "dog"}EXAMPLE 2User's Request: Detect the sparkly stiletto shoeOriginal concept: "Sparkly stiletto shoe"Final output:{"reasoning": "The provided image does not specific detections that correspond for 'Sparkly stiletto shoe'. 'Sparkly stiletto shoe' might be too specific for the model. Refining to 'shoe', a more generic concept might increase the likelihood of detection.","refined_list": "shoe"}EXAMPLE 3User's Request: Detect the hydrangeaOriginal concept: "Hydrangea"Final output:{"reasoning": "No detections found for 'hydrangea'. The model might struggle with specific flower types. Refining to the more general concept 'flower' could yield better results.","refined_list": "flower"}EXAMPLE 4User's Request: Detect the gourmet cheeseburgerOriginal concept: "Gourmet cheeseburger"Final output:{"reasoning": "No detections observed for 'Gourmet cheeseburger'. 'Gourmet cheeseburger' might be too specific. Refining to 'hamburger' as it aligns with the detected object.","refined_list": "hamburger"}EXAMPLE 5User's Request: Detect the red sports carOriginal concept: "Red sports car"Final output:{"reasoning": "The provided image does not have any reliable detections for 'red sports car'. Color-based detection might be challenging. Refining to the more general concept 'car' could improve detection.","refined_list": "car"}Remember:• If no refinement is needed (the concept is recognized well), explain that in the reasoning and return the same concept.• When refinement is necessary, prioritize more generic or abstract categories that may be more reliably detected by the model.• Provide only the JSON.• No extra commentary."""},{"role": "user", "content": [{"type": "text", "text": f"User's request: {user_request}\n Original Concepts for Detection: {original_concepts}"},{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_labeled_image}", "detail": "high"}}]}]refine_response = self.vlm_tool.chat_completion(refine_messages, model=model, response_format={"type": "json_object"})refined_response_objects = json.loads(refine_response)["refined_list"].split(",")if not refined_response_objects:return []refined_list = [r.strip().lower() for r in refined_response_objects if r.strip()]return refined_list
仅当优化后的列表与原始列表不同时,系统才会支付第二次检测器调用的成本——用新类别重新运行物体检测。这意味着额外推理算力会被精准投放于首次尝试未能弥合用户意图与检测器词汇库差距的场景。简言之,LLM将用户请求映射至检测器更熟悉的类别,为其提供通过二次调用获取有效输出的机会。
07
基于VLM的边界框验证机制
标注箭头的图像经编码后传入视觉语言模型,系统要求模型根据用户指令判断每个编号框的接受或拒绝状态。输出必须为严格JSON格式(例如{"3": "杯", "5": "茶壶"})以确保可解析性。这标志着验证流程进入新阶段——通过视觉语言模型对检测器输出进行筛选。
def _validate_bboxes_with_llm(self, user_request, labeled_image_path, model="o1"):"""Pass the labeled image to the LLM to filter bounding boxesbased on user request. Returns 'valid_numbers' list."""base64_labeled_image = encode_image(labeled_image_path)messages = [{"role": "system", "content": "You are an AI reviewing an object detection output.\n""All detected objects have been marked with an arrow mapping to a corresponding number.\n""The image contains arrows labeled with numbers pointing to specific objects.\n""Your task is to identify the objects indicated by these arrows and determine whether each detected object is relevant to the user's query.\n""For each numbered arrow:\n""1. Identify the object being pointed to.\n""2. Provide a brief description of the object (e.g., 'top-left cup with blue leaves', 'bottom-right cup with watermelon pattern', or 'background birdcage').\n""3. Analyze whether the object is valid based on the context and the user's instructions.\n""4. Provide a clear, step-by-step explanation for each object's validity decision.\n""Return a JSON object with the reasoning and list of valid numbers matching the user's request.\n""Example output:\n""{ \"reasoning\": <reasoning> , \"valid_numbers\": {object_num :\"object_name\"} }"},{"role": "user", "content": [{"type": "text", "text": f"The user's original request was: {user_request}"},{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_labeled_image}", "detail": "high"}}]}]valid_numbers_json = self.vlm_tool.chat_completion(messages,model=model,response_format={"type": "json_object"})try:valid_numbers_data = json.loads(valid_numbers_json)return valid_numbers_data.get("valid_numbers", {})except json.JSONDecodeError:return []
当优化后的概念列表第二次通过物体检测器后,流程转入预测结果校验环节。新的边界框被绘制到原始图像上,每个框均标注箭头和索引编号。系统并非单独发送每个裁剪区域,而是将整幅带箭头的图像进行Base64编码后一次性传输给视觉语言模型。
该验证步骤聚焦于核心判断:如示例所示,7号框是否完全符合用户需求?系统提示强制模型以严格JSON映射格式(如{"3": "杯", "5": "茶壶"})作答。数字编号与箭头标记严格对应,使得代码能明确接受或拒绝边界框,避免任何模糊匹配。
简言之,两个视觉语言模型步骤前后衔接:当初始查询的首轮预测不理想时,第一阶段重写用户查询以适配检测器词汇表;第二阶段则审核筛选模型预测,输出最终结果。
最终获得的预测结果将以边界框形式重新绘制在图像上。整合完整流程后,我们的最终实施方案如下:
def run(self, image_path, user_request, do_critique=True):"""Full pipeline:1. Extract objects from user request (LLM).2. Detect bounding boxes with that query.3. LLM-based validation step => filter bounding boxes.4. (Optional) Critique Step => refine the query if needed.5. Re-run detection with refined queries.6. Final LLM validation => final bounding boxes and annotation."""# ---------------------------------------------------# Step 1: initial user queries from request# ---------------------------------------------------objects_to_detect = self.vlm_tool.extract_objects_from_request(image_path, user_request, model=self.concept_detection_model)if not objects_to_detect:return None, "⚠️ No objects to detect or invalid request."# ---------------------------------------------------# Step 2: run detection with the initial user queries# ---------------------------------------------------detected_objects_final, labeled_image_path = self._run_detector(image_path, objects_to_detect)# ------------------------------------------------------# Step 3: Initial Critique and Object Concept Refinement# ------------------------------------------------------if do_critique:current_labels = ",".join(set([str(lbl) for _, lbl, _ in detected_objects_final]))refined_query_list = self._critique_and_refine_query(user_request=user_request,original_concepts=current_labels,labeled_image_path=labeled_image_path,objects_detected=current_labels,model=self.initial_critique_model)# If the refined list is empty or identical, we might skip re-running# But let's suppose we only re-run if we actually get a new set.if refined_query_list and set(refined_query_list) != set(objects_to_detect):# Re-run detection with refined querydetected_objects_final, labeled_image_path = self._run_detector(image_path, refined_query_list)if not detected_objects_final:return None, "No objects found for the initial query."# ---------------------------------------------------# Step 4: LLM-based critique# ---------------------------------------------------valid_numbers = self._validate_bboxes_with_llm(user_request, labeled_image_path, model=self.final_critique_model)# filter bounding boxesif valid_numbers:filtered_objects = [(n, valid_numbers[str(n)], box) for (n, lbl, box) in detected_objects_final if str(n) in valid_numbers]else:filtered_objects = detected_objects_final# store themself.last_detection_bboxes = [x[-1] for x in filtered_objects]self.last_filtered_objects = filtered_objects# ---------------------------------------------------# Step 5: Produce final annotated image# ---------------------------------------------------final_img = draw_bounding_boxes(image_path, filtered_objects)final_text = (f"🔍 Validated objects: {', '.join(set(str(lbl) for _, lbl, _ in filtered_objects))}")return final_img, final_text
该类的完整实现代码可通过此链接获取。
链接:
https://github.com/anand-subu/blog_resources/blob/main/agentic_object_detection/models/object_detection_tool.py
08
验证结果
我们实现了这一功能,并通过 Gradio 应用将其开放使用。为演示该流程的运行效果,我们使用了一张示例图片进行测试。通过输入提示“检测左上角的 iPod 和右下角的 iPhone”,我们验证了智能体的目标检测能力。该流程首先提取这两个设备概念,运行检测器,必要时利用大语言模型(LLM)进行概念扩展或细化,最终对每个编号的检测框进行逐一验证。

我们可以查看中间结果进行分析:用户输入图如下所示

执行开放性目标检测器后的输出如下:

对检测结果进行编号如下:

利用VLM做过滤验证优化后结果如下:

这个例子突显了该流程的一个关键优势:方向性精准定位。开放词汇检测器本身已能出色识别 iPhone 和 iPod,具备很高的召回率。而视觉语言模型(VLM)会对整个带箭头标注的图像进行全局推理,仅精确定位符合用户空间指令的设备。通过这种全局化、上下文感知的检测过滤机制,系统实现了超高精度,确保返回的结果完全符合用户提示要求。
我们通过第二个示例进一步展示了该流程的优势。使用一张包含两个咖啡杯的图片(每杯都有拉花图案),我们要求智能代理系统仅检测带有"Coffee Chat"拉花的咖啡杯。

我们可以查看中间结果进行分析:用户输入图如下所示

执行开放性目标检测器后的输出如下:

对检测结果进行编号如下:

利用VLM做过滤验证优化后结果如下:

这个案例展现了智能视觉工作流的另一大优势:精准识别含文字信息的物体。在上述的示例中,检测器虽然成功标记出两个咖啡杯(实现了高召回率),但其中只有一个杯子带有用户指定的"Coffee Chat?"拉花文字。由于视觉语言模型(VLM)能审阅整个带箭头标注的图像,并理解每个杯身印刷的文字内容,它能自动过滤无关的杯子,仅保留符合查询要求的预测结果。这种物体检测器所不具备的文字感知推理能力,确保了系统能获得高度精准的目标检测结果。
09
结论
自主目标检测(Agentic Object Detection)为获取精准的物体检测结果提供了一个强大而灵活的框架。本文展示了如何通过视觉语言模型(VLM)构建的智能代理层来增强开放词汇检测器(如 Grounding DINO)的能力。该代理不仅能解读和优化用户请求,还能结合上下文对检测器的输出进行校验与验证,从而生成更精准、更符合用户需求的结果。通过将检测与推理相结合,该系统实现了从简单物体识别到针对性视觉理解的跨越。
当前流程的一个主要局限是:其检测能力完全依赖于底层开放词汇检测器的认知范围。若用户请求检测的类别(如特定花卉或新型电子设备)超出检测器的识别能力,那么无论视觉语言模型如何进行推理修正都无济于事——因为现有流程仅将 VLM 用于对初始检测结果的审核与优化。值得注意的是,当前 OpenAI 的 GPT-4o、Google Gemini 等前沿视觉语言模型已能直接生成边界框作为多模态输出的一部分。随着技术发展,目标检测等能力正逐渐被整合到 VLM 的训练过程中,而非依赖独立系统实现。
如何学习AI大模型 ?
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。【保证100%免费】🆓
这份完整版的 AI 大模型学习资料已经上传CSDN,朋友们如果需要可以扫描下方二维码&点击下方CSDN官方认证链接免费领取 【保证100%免费】
读者福利: 👉👉CSDN大礼包:《最新AI大模型学习资源包》免费分享 👈👈
(👆👆👆安全链接,放心点击)
对于0基础小白入门:
如果你是零基础小白,想快速入门大模型是可以考虑的。
一方面是学习时间相对较短,学习内容更全面更集中。
二方面是可以根据这些资料规划好学习计划和方向。
要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。
对于从来没有接触过AI大模型的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。(全套教程文末领取哈)
很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,每个章节都是当前板块的精华浓缩。

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。(全套教程文末领取哈)

光学理论是没用的,要学会跟着一起做,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战项目来学习。(全套教程文末领取哈)
随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。(全套教程文末领取哈)
截至目前大模型已经超过200个,在大模型纵横的时代,不仅大模型技术越来越卷,就连大模型相关的岗位和面试也开始越来越卷了。为了让大家更容易上车大模型算法赛道,我总结了大模型常考的面试题。(全套教程文末领取哈)
只要你是真心想学AI大模型,我这份资料就可以无偿分享给你学习,我国在这方面的相关人才比较紧缺,大模型行业确实也需要更多的有志之士加入进来,我也真心希望帮助大家学好这门技术,如果日后有什么学习上的问题,欢迎找我交流,有技术上面的问题,我是很愿意去帮助大家的!
这份资料由我和鲁为民博士共同整理,鲁为民博士先后获得了北京清华大学学士和美国加州理工学院博士学位,在包括IEEE Transactions等学术期刊和诸多国际会议上发表了超过50篇学术论文、取得了多项美国和中国发明专利,同时还斩获了吴文俊人工智能科学技术奖。目前我正在和鲁博士共同进行人工智能的研究。
资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。


这份完整版的 AI 大模型学习资料已经上传CSDN,朋友们如果需要可以扫描下方二维码&点击下方CSDN官方认证链接免费领取 【保证100%免费】
(👆👆👆安全链接,放心点击)
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)