You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于YOLOv8已检测的目标区域实现二次类别检测?

如何基于YOLOv8已检测的目标区域实现二次类别检测?

嘿,我完全懂你的需求——先定位到第一个目标,再在它的范围内做二次检测对吧?其实这个思路特别直接,核心就是把第一次检测出的目标区域从原图里抠出来,把这个裁剪后的小图像当成新的输入,传给检测模型(可以是同一个模型的其他类别,也可以是专门训练的第二个模型)就行。下面给你一步步拆解实操方法:

第一步:从原图中裁剪出已检测到的目标区域

你已经通过YOLOv8拿到了目标的坐标cords(格式是[x1, y1, x2, y2]),接下来只要用这个坐标从原图像里把对应区域切出来就行。这里要注意OpenCV的图像格式是(高, 宽, 通道),所以切片的时候要对应成[y1:y2, x1:x2]。

第二步:对裁剪后的区域执行二次检测

拿到裁剪后的小图后,就可以像第一次检测那样,用YOLOv8加载模型(如果是检测另一个类,要么用包含该类的模型,要么用专门训练的第二个模型),然后对小图做预测就行。

给你修改后的完整代码示例

我把你的代码做了扩展,加入了二次检测的逻辑,你可以根据自己的实际情况调整:

import cv2
from ultralytics import YOLO

# 加载第一次检测的模型(检测myclassname的模型)
primary_model = YOLO('runs/detect/train4/weights/best.pt')
# 加载二次检测的模型——如果是同一个模型包含第二个类,就用上面的primary_model;如果是单独训练的,就换路径
secondary_model = YOLO('runs/detect/train_second_class/weights/best.pt')  # 替换成你的二次检测模型路径

# 读取原图
image = cv2.imread("screenshot.png")

# 第一次检测:定位目标区域
results = primary_model.predict(image, show=False, stream=True, classes=0, imgsz=512)

for result in results:
    for box in result.boxes:
        class_id = result.names[box.cls[0].item()]
        if class_id == "myclassname":
            cords = box.xyxy[0].tolist()
            cords = [round(x) for x in cords]
            x1, y1, x2, y2 = cords
            print("第一次检测结果:")
            print("Object type:", class_id)
            print("Coordinates:", cords)
            print("Probability:", round(box.conf[0].item(), 2))
            print("---")

            # 裁剪目标区域:注意OpenCV的图像维度是(y, x, channel)
            # 先确保坐标在图像范围内,避免索引越界
            x1 = max(0, x1)
            y1 = max(0, y1)
            x2 = min(image.shape[1], x2)
            y2 = min(image.shape[0], y2)
            cropped_region = image[y1:y2, x1:x2]

            # 对裁剪后的区域做二次检测
            print("开始二次检测...")
            secondary_results = secondary_model.predict(cropped_region, show=True, imgsz=512)
            # 如果是用同一个模型检测其他类,可以指定classes参数,比如classes=1(假设第二个类的id是1)
            # secondary_results = primary_model.predict(cropped_region, show=True, imgsz=512, classes=1)

            for sec_result in secondary_results:
                for sec_box in sec_result.boxes:
                    sec_class_id = sec_result.names[sec_box.cls[0].item()]
                    sec_cords = sec_box.xyxy[0].tolist()
                    sec_cords = [round(x) for x in sec_cords]
                    sec_conf = round(sec_box.conf[0].item(), 2)
                    print("二次检测结果:")
                    print("Object type:", sec_class_id)
                    print("Coordinates(相对于裁剪区域):", sec_cords)
                    print("Probability:", sec_conf)
                    print("---")

一些注意事项

  • 如果你的两个类别是在同一个YOLO模型里训练的,那不需要加载第二个模型,只要在二次检测的时候调整classes参数,指定你要检测的第二个类的ID就行。
  • 裁剪区域的时候一定要做坐标边界检查(max(0, x1)和min(image.shape[1], x2)),避免因为目标靠近图像边缘导致索引越界报错。
  • 如果二次检测的目标很小,可以适当调整imgsz参数,让模型更精准地识别小目标。

备注:内容来源于stack exchange,提问作者GN Chishti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 14:18:05