欢迎光临
我们一直在努力

YOLO12代码实例:Python requests调用/predict接口并解析JSON结果

YOLO12代码实例:Python requests调用/predict接口并解析JSON结果

1. 引言

目标检测是计算机视觉领域的核心任务之一,而YOLO系列模型一直是这个领域的标杆。YOLO12作为Ultralytics在2025年推出的最新版本,在保持实时推理速度的同时,通过引入注意力机制进一步提升了检测精度。

在实际项目中,我们往往需要通过编程方式调用模型的API接口,而不是手动在Web界面上传图片。本文将详细介绍如何使用Python的requests库调用YOLO12的/predict接口,并完整解析返回的JSON结果。无论你是想要将目标检测功能集成到自己的应用中,还是需要进行批量图片处理,这个教程都能帮你快速上手。

2. 环境准备与快速部署

2.1 部署YOLO12镜像

首先需要在平台上部署YOLO12镜像:

  • 在镜像市场搜索 ins-yolo12-independent-v1
  • 选择对应的计算规格(建议至少4GB显存)
  • 点击"部署实例",等待状态变为"已启动"
  • 部署完成后,你会获得一个实例IP地址,后续的API调用都将基于这个地址。

    2.2 验证服务状态

    部署完成后,可以通过以下方式验证服务是否正常:

    # 检查API服务
    curl http://<实例IP>:8000/docs

    # 检查WebUI服务
    # 在浏览器中访问 http://<实例IP>:7860

    如果服务正常,API检查应该返回FastAPI的交互式文档页面。

    3. Python requests基础调用

    3.1 安装必要库

    确保你的Python环境中有requests库:

    pip install requests pillow

    Pillow库用于图片处理,虽然不是必须的,但在实际项目中很实用。

    3.2 最简单的调用示例

    下面是一个最基本的调用示例:

    import requests
    import json

    def detect_objects_simple(image_path, server_url):
    """
    最简单的YOLO12目标检测调用

    Args:
    image_path: 图片文件路径
    server_url: 服务器地址,如 http://192.168.1.100:8000
    """
    # 准备请求
    url = f"{server_url}/predict"
    files = {'file': open(image_path, 'rb')}

    try:
    # 发送请求
    response = requests.post(url, files=files)
    response.raise_for_status() # 检查请求是否成功

    # 解析结果
    result = response.json()
    print(json.dumps(result, indent=2))

    return result

    except requests.exceptions.RequestException as e:
    print(f"请求失败: {e}")
    return None
    finally:
    files['file'].close()

    # 使用示例
    if __name__ == "__main__":
    result = detect_objects_simple('test.jpg', 'http://localhost:8000')

    这个简单的例子展示了如何用最少的代码调用YOLO12接口。在实际使用中,你需要将localhost:8000替换为你的实际服务器地址。

    4. 完整的功能实现

    4.1 带错误处理的完整函数

    在实际项目中,我们需要更完善的错误处理和功能:

    import requests
    import json
    from PIL import Image, ImageDraw, ImageFont
    import os
    import time

    class YOLO12Client:
    def __init__(self, server_url, timeout=30):
    """
    初始化YOLO12客户端

    Args:
    server_url: 服务器地址,如 http://192.168.1.100:8000
    timeout: 请求超时时间(秒)
    """
    self.server_url = server_url.rstrip('/')
    self.timeout = timeout
    self.predict_url = f"{self.server_url}/predict"

    def detect_objects(self, image_path, confidence=0.25, visualize=False):
    """
    检测图片中的物体

    Args:
    image_path: 图片路径或PIL Image对象
    confidence: 置信度阈值
    visualize: 是否返回可视化图片

    Returns:
    dict: 检测结果
    """
    # 准备请求参数
    files = {'file': self._prepare_image(image_path)}
    params = {'confidence': confidence}

    if visualize:
    params['visualize'] = 'true'

    try:
    # 发送请求
    start_time = time.time()
    response = requests.post(
    self.predict_url,
    files=files,
    params=params,
    timeout=self.timeout
    )
    response.raise_for_status()

    # 计算处理时间
    processing_time = time.time() – start_time

    # 解析结果
    result = response.json()
    result['processing_time'] = processing_time

    return result

    except requests.exceptions.Timeout:
    raise Exception("请求超时,请检查网络连接或服务器状态")
    except requests.exceptions.ConnectionError:
    raise Exception("无法连接到服务器,请检查服务器地址和端口")
    except requests.exceptions.HTTPError as e:
    raise Exception(f"服务器返回错误: {e}")
    except Exception as e:
    raise Exception(f"检测失败: {e}")
    finally:
    if isinstance(image_path, str) and 'file' in locals():
    files['file'].close()

    def _prepare_image(self, image_input):
    """
    准备图片数据

    Args:
    image_input: 图片路径或PIL Image对象

    Returns:
    file-like object: 准备好的图片文件
    """
    if isinstance(image_input, str):
    # 如果是文件路径
    if not os.path.exists(image_input):
    raise FileNotFoundError(f"图片文件不存在: {image_input}")
    return open(image_input, 'rb')
    else:
    # 如果是PIL Image对象
    from io import BytesIO
    img_byte_arr = BytesIO()
    image_input.save(img_byte_arr, format='JPEG')
    img_byte_arr.seek(0)
    return img_byte_arr

    def batch_detect(self, image_paths, confidence=0.25):
    """
    批量检测多张图片

    Args:
    image_paths: 图片路径列表
    confidence: 置信度阈值

    Returns:
    list: 每张图片的检测结果
    """
    results = []
    for image_path in image_paths:
    try:
    result = self.detect_objects(image_path, confidence)
    results.append({
    'image': image_path,
    'result': result,
    'success': True
    })
    except Exception as e:
    results.append({
    'image': image_path,
    'error': str(e),
    'success': False
    })

    return results

    # 使用示例
    if __name__ == "__main__":
    # 初始化客户端
    client = YOLO12Client('http://localhost:8000')

    # 单张图片检测
    result = client.detect_objects('test.jpg', confidence=0.3)
    print(f"检测到 {len(result['detections'])} 个物体")
    print(f"处理时间: {result['processing_time']:.2f}秒")

    # 批量检测
    image_list = ['image1.jpg', 'image2.jpg', 'image3.jpg']
    batch_results = client.batch_detect(image_list)

    for res in batch_results:
    if res['success']:
    print(f"{res['image']}: 检测到 {len(res['result']['detections'])} 个物体")
    else:
    print(f"{res['image']}: 检测失败 – {res['error']}")

    4.2 解析JSON结果

    YOLO12返回的JSON结果包含丰富的信息,下面是一个典型的返回结果:

    {
    "success": true,
    "message": "Detection completed",
    "detections": [
    {
    "class": "person",
    "confidence": 0.92,
    "bbox": [123, 45, 234, 567],
    "bbox_normalized": [0.192, 0.070, 0.366, 0.886]
    },
    {
    "class": "car",
    "confidence": 0.88,
    "bbox": [345, 123, 567, 234],
    "bbox_normalized": [0.539, 0.192, 0.886, 0.366]
    }
    ],
    "image_info": {
    "width": 640,
    "height": 640,
    "format": "JPEG"
    },
    "model_info": {
    "name": "yolov12n.pt",
    "version": "1.0"
    },
    "inference_time": 0.0076
    }

    4.3 结果解析工具函数

    为了更方便地使用检测结果,我们可以编写一些工具函数:

    def analyze_detections(result, min_confidence=0.5):
    """
    分析检测结果

    Args:
    result: API返回的JSON结果
    min_confidence: 最小置信度阈值

    Returns:
    dict: 分析结果
    """
    if not result.get('success', False):
    return {"error": "检测失败"}

    detections = result.get('detections', [])

    # 过滤低置信度的检测结果
    filtered_detections = [
    d for d in detections
    if d.get('confidence', 0) >= min_confidence
    ]

    # 统计各类别的数量
    class_counts = {}
    for detection in filtered_detections:
    class_name = detection.get('class', 'unknown')
    class_counts[class_name] = class_counts.get(class_name, 0) + 1

    # 计算平均置信度
    avg_confidence = sum(
    d.get('confidence', 0) for d in filtered_detections
    ) / len(filtered_detections) if filtered_detections else 0

    return {
    'total_detections': len(detections),
    'filtered_detections': len(filtered_detections),
    'class_counts': class_counts,
    'avg_confidence': avg_confidence,
    'inference_time': result.get('inference_time', 0)
    }

    def draw_detections(image_path, result, output_path=None, min_confidence=0.25):
    """
    在图片上绘制检测框

    Args:
    image_path: 原始图片路径
    result: 检测结果
    output_path: 输出图片路径(如果为None则不保存)
    min_confidence: 最小置信度阈值

    Returns:
    PIL.Image: 绘制了检测框的图片
    """
    # 打开原始图片
    image = Image.open(image_path)
    draw = ImageDraw.Draw(image)

    # 尝试加载字体
    try:
    font = ImageFont.truetype("Arial", 15)
    except:
    font = ImageFont.load_default()

    # 颜色映射(为不同类别分配不同颜色)
    colors = {
    'person': 'red',
    'car': 'blue',
    'dog': 'green',
    'cat': 'orange'
    }

    # 绘制每个检测框
    for detection in result.get('detections', []):
    if detection.get('confidence', 0) < min_confidence:
    continue

    class_name = detection.get('class', 'unknown')
    confidence = detection.get('confidence', 0)
    bbox = detection.get('bbox', [])

    if len(bbox) != 4:
    continue

    # 选择颜色
    color = colors.get(class_name, 'white')

    # 绘制矩形框
    draw.rectangle(bbox, outline=color, width=2)

    # 绘制标签背景
    label = f"{class_name} {confidence:.2f}"
    bbox_text = draw.textbbox((0, 0), label, font=font)
    text_width = bbox_text[2] – bbox_text[0]
    text_height = bbox_text[3] – bbox_text[1]

    draw.rectangle(
    [bbox[0], bbox[1] – text_height – 5,
    bbox[0] + text_width + 10, bbox[1]],
    fill=color
    )

    # 绘制文本
    draw.text(
    (bbox[0] + 5, bbox[1] – text_height – 2),
    label,
    fill='white',
    font=font
    )

    # 保存或返回图片
    if output_path:
    image.save(output_path)

    return image

    # 使用示例
    if __name__ == "__main__":
    client = YOLO12Client('http://localhost:8000')
    result = client.detect_objects('test.jpg')

    # 分析结果
    analysis = analyze_detections(result, min_confidence=0.5)
    print(f"检测统计: {analysis}")

    # 绘制检测框
    output_image = draw_detections('test.jpg', result, 'output.jpg', min_confidence=0.3)
    output_image.show()

    5. 实际应用场景

    5.1 安防监控集成

    class SecurityMonitor:
    def __init__(self, yolo_client, alert_classes=['person', 'car']):
    """
    安防监控集成示例

    Args:
    yolo_client: YOLO12客户端实例
    alert_classes: 需要报警的物体类别
    """
    self.client = yolo_client
    self.alert_classes = alert_classes
    self.detection_history = []

    def monitor_frame(self, frame_path, confidence_threshold=0.7):
    """
    监控单帧画面

    Args:
    frame_path: 帧图片路径
    confidence_threshold: 置信度阈值

    Returns:
    dict: 监控结果和报警信息
    """
    result = self.client.detect_objects(frame_path, confidence=confidence_threshold)

    if not result.get('success', False):
    return {'alert': False, 'error': '检测失败'}

    # 检查是否需要报警
    alerts = []
    for detection in result.get('detections', []):
    if detection.get('class') in self.alert_classes:
    alerts.append({
    'class': detection.get('class'),
    'confidence': detection.get('confidence', 0),
    'bbox': detection.get('bbox', [])
    })

    # 记录检测历史
    self.detection_history.append({
    'timestamp': time.time(),
    'detections': result.get('detections', []),
    'alerts': alerts
    })

    # 保持历史记录长度
    if len(self.detection_history) > 1000:
    self.detection_history = self.detection_history[-1000:]

    return {
    'alert': len(alerts) > 0,
    'alerts': alerts,
    'total_detections': len(result.get('detections', [])),
    'inference_time': result.get('inference_time', 0)
    }

    def generate_report(self, time_window=3600):
    """
    生成监控报告

    Args:
    time_window: 时间窗口(秒)

    Returns:
    dict: 监控报告
    """
    current_time = time.time()
    recent_detections = [
    d for d in self.detection_history
    if d['timestamp'] > current_time – time_window
    ]

    # 统计各类别的出现次数
    class_stats = {}
    for detection in recent_detections:
    for det in detection['detections']:
    class_name = det.get('class', 'unknown')
    class_stats[class_name] = class_stats.get(class_name, 0) + 1

    # 统计报警次数
    alert_stats = {}
    for detection in recent_detections:
    for alert in detection['alerts']:
    class_name = alert.get('class', 'unknown')
    alert_stats[class_name] = alert_stats.get(class_name, 0) + 1

    return {
    'time_window': time_window,
    'total_frames': len(recent_detections),
    'class_statistics': class_stats,
    'alert_statistics': alert_stats,
    'average_inference_time': sum(
    d.get('inference_time', 0) for d in recent_detections
    ) / len(recent_detections) if recent_detections else 0
    }

    5.2 批量图片处理

    def process_image_dataset(dataset_folder, output_folder, confidence=0.3):
    """
    处理整个图片数据集

    Args:
    dataset_folder: 数据集文件夹路径
    output_folder: 输出文件夹路径
    confidence: 置信度阈值
    """
    client = YOLO12Client('http://localhost:8000')

    # 创建输出文件夹
    os.makedirs(output_folder, exist_ok=True)
    os.makedirs(os.path.join(output_folder, 'annotations'), exist_ok=True)
    os.makedirs(os.path.join(output_folder, 'visualizations'), exist_ok=True)

    # 获取所有图片文件
    image_extensions = ['.jpg', '.jpeg', '.png', '.bmp']
    image_files = []
    for ext in image_extensions:
    image_files.extend(
    [f for f in os.listdir(dataset_folder) if f.lower().endswith(ext)]
    )

    results = []
    for image_file in image_files:
    try:
    image_path = os.path.join(dataset_folder, image_file)

    # 检测物体
    result = client.detect_objects(image_path, confidence=confidence)

    # 保存原始结果
    base_name = os.path.splitext(image_file)[0]
    result_path = os.path.join(output_folder, 'annotations', f'{base_name}.json')
    with open(result_path, 'w') as f:
    json.dump(result, f, indent=2)

    # 生成可视化图片
    vis_image = draw_detections(image_path, result, min_confidence=confidence)
    vis_path = os.path.join(output_folder, 'visualizations', f'{base_name}_detected.jpg')
    vis_image.save(vis_path)

    # 记录结果
    results.append({
    'image': image_file,
    'success': True,
    'detections': len(result.get('detections', [])),
    'inference_time': result.get('inference_time', 0)
    })

    print(f"处理完成: {image_file} – 检测到 {len(result.get('detections', []))} 个物体")

    except Exception as e:
    results.append({
    'image': image_file,
    'success': False,
    'error': str(e)
    })
    print(f"处理失败: {image_file} – {e}")

    # 生成汇总报告
    summary = {
    'total_images': len(image_files),
    'processed_successfully': sum(1 for r in results if r['success']),
    'total_detections': sum(r.get('detections', 0) for r in results if r['success']),
    'average_inference_time': sum(
    r.get('inference_time', 0) for r in results if r['success']
    ) / sum(1 for r in results if r['success']) if any(r['success'] for r in results) else 0,
    'failed_images': [r['image'] for r in results if not r['success']]
    }

    with open(os.path.join(output_folder, 'processing_summary.json'), 'w') as f:
    json.dump(summary, f, indent=2)

    return summary

    6. 总结

    通过本文的详细介绍,你应该已经掌握了如何使用Python requests库调用YOLO12的/predict接口,并解析返回的JSON结果。关键要点包括:

  • 基础调用:使用requests库的files参数上传图片,处理返回的JSON数据
  • 错误处理:完善的异常处理机制,确保程序稳定性
  • 结果解析:理解YOLO12返回的数据结构,提取边界框、置信度、类别等信息
  • 实用工具:提供了结果分析、可视化、批量处理等实用功能
  • 实际应用:展示了安防监控和批量处理等实际应用场景
  • YOLO12提供的RESTful API使得集成目标检测功能到各种应用中变得非常简单。无论是开发监控系统、处理图片数据集,还是构建智能相册应用,都可以通过本文介绍的方法快速实现。

    记得在实际使用时,根据你的具体需求调整置信度阈值,并在生产环境中添加重试机制和日志记录等功能,确保系统的稳定性和可靠性。


    获取更多AI镜像

    想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

    赞(0)
    未经允许不得转载:171主机测评 » YOLO12代码实例:Python requests调用/predict接口并解析JSON结果
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址