
DAMO-YOLO基础教程PyTorch模型加载、推理、后处理全流程代码想用DAMO-YOLO做目标检测但面对一堆代码和模型文件不知道从哪下手别担心这篇文章就是为你准备的。我会带你一步步走完从加载模型到输出检测结果的完整流程用最直白的语言和可运行的代码让你快速掌握这个高性能检测器的核心用法。DAMO-YOLO是阿里达摩院推出的目标检测算法它在速度和精度之间找到了很好的平衡点。今天我们不谈复杂的理论就聚焦一件事给你一套能直接运行的代码让你能用自己的图片测试这个模型。1. 环境准备与快速开始在开始写代码之前我们需要先把环境准备好。这个过程很简单跟着做就行。1.1 安装必要的库首先确保你的Python环境已经安装了PyTorch。如果没有可以去PyTorch官网按照指引安装。然后我们还需要安装几个辅助库。打开你的终端或命令行运行下面的命令pip install opencv-python pillow numpy这三个库分别用来处理图片、显示图片和进行数学计算都是深度学习项目中常用的工具。1.2 下载预训练模型DAMO-YOLO提供了多个预训练模型你可以根据需求选择。这里我们以DAMO-YOLO-Tiny模型为例它速度快适合快速验证和部署。模型文件通常是一个.pth文件你可以从官方仓库或模型平台下载。下载后把它放在一个你记得住的文件夹里比如./models/。如果你不想自己下载也可以使用ModelScope阿里云的开源模型社区来加载模型这样更简单。我们后面会介绍两种方法。2. 核心代码三步搞定目标检测目标检测的完整流程可以概括为三步加载模型、推理图片、处理结果。下面我们分别来看每一步怎么写代码。2.1 第一步加载模型加载模型就是把训练好的“大脑”读入到我们的程序里让它准备好识别物体。这里我给出两种方法。方法一直接加载本地模型文件推荐如果你已经下载了.pth模型文件可以用下面的代码加载import torch import cv2 import numpy as np from PIL import Image import torchvision.transforms as transforms def load_model_local(model_path): 从本地文件加载DAMO-YOLO模型 # 注意这里需要根据你实际使用的模型类来初始化 # 假设我们有一个简单的模型类定义实际使用时需要替换为真实的模型类 class SimpleDAMOYOLO(torch.nn.Module): def __init__(self): super(SimpleDAMOYOLO, self).__init__() # 这里应该是实际的模型结构 # 为了示例我们创建一个简单的占位模型 self.backbone torch.nn.Sequential( torch.nn.Conv2d(3, 64, kernel_size3, padding1), torch.nn.ReLU(), ) self.detection_head torch.nn.Conv2d(64, 85, kernel_size1) # 85 4180 (boxconfclass) def forward(self, x): features self.backbone(x) predictions self.detection_head(features) return predictions # 创建模型实例 model SimpleDAMOYOLO() # 加载预训练权重 checkpoint torch.load(model_path, map_locationcpu) # 不同的模型保存方式可能不同需要根据实际情况调整 if model in checkpoint: model.load_state_dict(checkpoint[model]) elif state_dict in checkpoint: model.load_state_dict(checkpoint[state_dict]) else: model.load_state_dict(checkpoint) # 设置为评估模式这很重要 model.eval() print(f模型从 {model_path} 加载成功) return model # 使用示例 model load_model_local(./models/damoyolo_tiny.pth)方法二使用ModelScope加载更方便如果你不想处理模型文件可以直接用ModelScope的API加载from modelscope.pipelines import pipeline from modelscope.utils.constant import Tasks def load_model_modelscope(): 使用ModelScope加载DAMO-YOLO模型 # 指定模型ID这里以DAMO-YOLO-Tiny为例 model_id damo/cv_tinynas_object-detection_damoyolo # 创建目标检测pipeline damoyolo_pipeline pipeline( Tasks.domain_specific_object_detection, modelmodel_id ) print(模型通过ModelScope加载成功) return damoyolo_pipeline # 使用示例 detector load_model_modelscope()两种方法各有优势第一种更灵活可以完全控制第二种更简单适合快速实验。你可以根据情况选择。2.2 第二步准备图片并推理模型加载好后我们需要给它“喂”图片。图片需要经过一些处理变成模型能理解的格式。def prepare_image(image_path, target_size640): 准备图片用于模型推理 # 读取图片 image Image.open(image_path).convert(RGB) original_size image.size # (宽度, 高度) # 定义图片预处理流程 transform transforms.Compose([ transforms.Resize((target_size, target_size)), # 调整大小 transforms.ToTensor(), # 转为Tensor transforms.Normalize(mean[0.485, 0.456, 0.406], # 归一化 std[0.229, 0.224, 0.225]) ]) # 应用预处理 input_tensor transform(image).unsqueeze(0) # 增加batch维度 return input_tensor, original_size, image def inference_with_local_model(model, image_path): 使用本地加载的模型进行推理 # 准备图片 input_tensor, original_size, original_image prepare_image(image_path) # 进行推理不计算梯度加快速度 with torch.no_grad(): predictions model(input_tensor) print(f推理完成输出形状: {predictions.shape}) return predictions, original_size, original_image def inference_with_modelscope(detector, image_path): 使用ModelScope pipeline进行推理 # ModelScope的pipeline可以直接处理图片路径 result detector(image_path) print(f推理完成检测到 {len(result[boxes])} 个目标) return result # 使用示例 # 方法一本地模型 # predictions, original_size, original_image inference_with_local_model(model, test.jpg) # 方法二ModelScope # result inference_with_modelscope(detector, test.jpg)这里有几个关键点需要注意图片需要调整到固定大小通常是640x640需要转换为Tensor格式需要进行归一化处理使用ImageNet的均值和标准差推理时要使用torch.no_grad()来节省内存2.3 第三步处理推理结果模型输出的结果是一堆数字我们需要把这些数字转换成我们能理解的信息框在哪里、是什么物体、置信度多少。def process_predictions(predictions, original_size, confidence_threshold0.5): 处理模型输出的预测结果 # 这里需要根据DAMO-YOLO的实际输出格式来解析 # 以下是一个简化的示例实际实现需要参考官方代码 # 假设predictions的形状是 [1, 85, 8400] (batch, features, anchors) # 实际格式可能不同需要根据模型调整 # 将预测结果从Tensor转换为numpy数组 pred_np predictions[0].detach().cpu().numpy() # 简化的后处理流程实际应该使用非极大值抑制NMS boxes [] scores [] class_ids [] # 遍历所有预测框 for i in range(pred_np.shape[1]): # 遍历8400个anchor # 获取这个anchor的预测 pred pred_np[:, i] # 解析边界框 (cx, cy, w, h 格式) cx, cy, w, h pred[0:4] # 解析置信度 obj_conf pred[4] # 解析类别概率 cls_probs pred[5:] cls_conf np.max(cls_probs) cls_id np.argmax(cls_probs) # 计算最终置信度 conf obj_conf * cls_conf # 过滤低置信度的预测 if conf confidence_threshold: # 将中心坐标转换为角点坐标 x1 cx - w / 2 y1 cy - h / 2 x2 cx w / 2 y2 cy h / 2 # 缩放回原始图片尺寸 scale_x original_size[0] / 640 # 假设输入尺寸是640 scale_y original_size[1] / 640 x1 int(x1 * scale_x) y1 int(y1 * scale_y) x2 int(x2 * scale_x) y2 int(y2 * scale_y) boxes.append([x1, y1, x2, y2]) scores.append(float(conf)) class_ids.append(int(cls_id)) # 应用非极大值抑制(NMS)去除重叠框 # 这里使用一个简单的NMS实现 def nms(boxes, scores, iou_threshold0.5): if len(boxes) 0: return [] boxes np.array(boxes) scores np.array(scores) # 按置信度排序 order scores.argsort()[::-1] keep [] while order.size 0: i order[0] keep.append(i) if order.size 1: break # 计算当前框与其他框的IoU xx1 np.maximum(boxes[i, 0], boxes[order[1:], 0]) yy1 np.maximum(boxes[i, 1], boxes[order[1:], 1]) xx2 np.minimum(boxes[i, 2], boxes[order[1:], 2]) yy2 np.minimum(boxes[i, 3], boxes[order[1:], 3]) w np.maximum(0.0, xx2 - xx1) h np.maximum(0.0, yy2 - yy1) inter w * h area_i (boxes[i, 2] - boxes[i, 0]) * (boxes[i, 3] - boxes[i, 1]) area_others (boxes[order[1:], 2] - boxes[order[1:], 0]) * (boxes[order[1:], 3] - boxes[order[1:], 1]) iou inter / (area_i area_others - inter) # 保留IoU小于阈值的框 inds np.where(iou iou_threshold)[0] order order[inds 1] return keep keep_indices nms(boxes, scores) final_boxes [boxes[i] for i in keep_indices] final_scores [scores[i] for i in keep_indices] final_class_ids [class_ids[i] for i in keep_indices] return final_boxes, final_scores, final_class_ids def process_modelscope_result(result): 处理ModelScope返回的结果 # ModelScope的结果已经是处理好的格式 boxes result[boxes] scores result[scores] labels result[labels] return boxes, scores, labels后处理是目标检测中最复杂的部分之一主要包括解析模型输出的原始数据过滤掉置信度低的预测应用非极大值抑制NMS去除重复框将坐标转换回原始图片尺寸3. 可视化结果让检测框显示在图片上检测结果是一堆坐标和数字不够直观。我们需要把它们画在图片上这样一眼就能看出模型检测得对不对。def visualize_results(image, boxes, scores, class_ids, class_namesNone): 在图片上可视化检测结果 # 如果没有提供类别名称使用COCO的80个类别 if class_names is None: class_names [ person, bicycle, car, motorcycle, airplane, bus, train, truck, boat, traffic light, fire hydrant, stop sign, parking meter, bench, bird, cat, dog, horse, sheep, cow, elephant, bear, zebra, giraffe, backpack, umbrella, handbag, tie, suitcase, frisbee, skis, snowboard, sports ball, kite, baseball bat, baseball glove, skateboard, surfboard, tennis racket, bottle, wine glass, cup, fork, knife, spoon, bowl, banana, apple, sandwich, orange, broccoli, carrot, hot dog, pizza, donut, cake, chair, couch, potted plant, bed, dining table, toilet, tv, laptop, mouse, remote, keyboard, cell phone, microwave, oven, toaster, sink, refrigerator, book, clock, vase, scissors, teddy bear, hair drier, toothbrush ] # 将PIL图片转换为OpenCV格式 if isinstance(image, Image.Image): image_cv cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR) else: image_cv image.copy() # 定义颜色BGR格式 colors [ (0, 255, 0), # 绿色 (255, 0, 0), # 蓝色 (0, 0, 255), # 红色 (255, 255, 0), # 青色 (255, 0, 255), # 紫色 (0, 255, 255), # 黄色 ] # 绘制每个检测框 for i, (box, score, class_id) in enumerate(zip(boxes, scores, class_ids)): x1, y1, x2, y2 map(int, box) # 选择颜色 color colors[class_id % len(colors)] # 绘制矩形框 cv2.rectangle(image_cv, (x1, y1), (x2, y2), color, 2) # 准备标签文本 label f{class_names[class_id]}: {score:.2f} # 计算文本大小 (text_width, text_height), baseline cv2.getTextSize( label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1 ) # 绘制文本背景 cv2.rectangle( image_cv, (x1, y1 - text_height - baseline - 5), (x1 text_width, y1), color, -1 # 填充 ) # 绘制文本 cv2.putText( image_cv, label, (x1, y1 - baseline - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), # 白色文字 1 ) # 显示图片 cv2.imshow(Detection Results, image_cv) cv2.waitKey(0) cv2.destroyAllWindows() # 保存结果 output_path detection_result.jpg cv2.imwrite(output_path, image_cv) print(f结果已保存到: {output_path}) return image_cv可视化部分主要做三件事把检测框画在图片上用不同颜色区分不同类别在每个框旁边标注类别名称和置信度显示并保存结果图片4. 完整示例从零到一的完整流程现在我们把所有代码组合起来形成一个完整的可运行示例。import torch import cv2 import numpy as np from PIL import Image import torchvision.transforms as transforms def main(): 完整的DAMO-YOLO目标检测流程示例 print( DAMO-YOLO 目标检测完整流程 ) # 1. 加载模型这里使用ModelScope方式更简单 print(\n1. 加载模型中...) from modelscope.pipelines import pipeline from modelscope.utils.constant import Tasks try: detector pipeline( Tasks.domain_specific_object_detection, modeldamo/cv_tinynas_object-detection_damoyolo ) print(✓ 模型加载成功) except Exception as e: print(f✗ 模型加载失败: {e}) print(请确保已安装modelscope: pip install modelscope) return # 2. 准备测试图片 print(\n2. 准备测试图片...) test_image_path test.jpg # 替换为你的图片路径 # 如果没有测试图片可以创建一个简单的示例图片 try: Image.open(test_image_path) print(f✓ 找到测试图片: {test_image_path}) except: print(✗ 未找到测试图片创建示例图片...) # 创建一个简单的测试图片 test_image np.ones((480, 640, 3), dtypenp.uint8) * 255 cv2.rectangle(test_image, (100, 100), (300, 300), (0, 0, 255), -1) # 红色矩形 cv2.rectangle(test_image, (350, 150), (550, 350), (255, 0, 0), -1) # 蓝色矩形 cv2.imwrite(test_image_path, test_image) print(f✓ 已创建示例图片: {test_image_path}) # 3. 进行推理 print(\n3. 进行推理...) try: result detector(test_image_path) print(f✓ 推理完成检测到 {len(result[boxes])} 个目标) except Exception as e: print(f✗ 推理失败: {e}) return # 4. 处理结果 print(\n4. 处理检测结果...) boxes result[boxes] scores result[scores] labels result[labels] # 过滤低置信度的结果 confidence_threshold 0.3 filtered_indices [i for i, score in enumerate(scores) if score confidence_threshold] filtered_boxes [boxes[i] for i in filtered_indices] filtered_scores [scores[i] for i in filtered_indices] filtered_labels [labels[i] for i in filtered_indices] print(f✓ 过滤后保留 {len(filtered_boxes)} 个目标 (阈值: {confidence_threshold})) # 5. 可视化结果 print(\n5. 可视化结果...) # 读取原始图片 original_image cv2.imread(test_image_path) # 绘制检测框 for i, (box, score, label) in enumerate(zip(filtered_boxes, filtered_scores, filtered_labels)): x1, y1, x2, y2 map(int, box) # 选择颜色基于标签 color (0, 255, 0) if i % 3 0 else (255, 0, 0) if i % 3 1 else (0, 0, 255) # 绘制矩形框 cv2.rectangle(original_image, (x1, y1), (x2, y2), color, 2) # 添加标签 label_text fObj {i}: {score:.2f} cv2.putText(original_image, label_text, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) # 显示结果 cv2.imshow(DAMO-YOLO Detection Results, original_image) print(✓ 结果显示中按任意键关闭窗口...) cv2.waitKey(0) cv2.destroyAllWindows() # 保存结果 output_path detection_output.jpg cv2.imwrite(output_path, original_image) print(f✓ 结果已保存到: {output_path}) # 6. 打印详细结果 print(\n6. 检测结果详情:) print(- * 50) for i, (box, score, label) in enumerate(zip(filtered_boxes, filtered_scores, filtered_labels)): x1, y1, x2, y2 map(int, box) print(f目标 {i1}:) print(f 位置: ({x1}, {y1}) 到 ({x2}, {y2})) print(f 大小: {x2-x1} x {y2-y1} 像素) print(f 置信度: {score:.4f}) print(f 标签ID: {label}) print() if __name__ __main__: main()这个完整示例包含了从加载模型到显示结果的所有步骤。你可以直接复制这段代码修改图片路径就能运行起来看到效果。5. 常见问题与实用技巧在实际使用中你可能会遇到一些问题。这里我总结了一些常见问题和解决方法。5.1 模型加载失败怎么办问题加载模型时出现错误比如找不到文件或格式不对。解决方法检查模型文件路径是否正确确保模型文件完整没有损坏如果是使用ModelScope检查网络连接查看错误信息通常会有具体提示# 更健壮的模型加载代码 def safe_load_model(model_path): try: checkpoint torch.load(model_path, map_locationcpu) print(模型文件加载成功) return checkpoint except FileNotFoundError: print(f错误找不到模型文件 {model_path}) print(请检查文件路径是否正确) except Exception as e: print(f加载模型时出错: {e}) print(可能是模型文件损坏或格式不正确) return None5.2 推理速度太慢怎么办问题处理一张图片要等很久。解决方法使用GPU加速如果有的话减小输入图片尺寸使用更小的模型版本# 使用GPU加速 device torch.device(cuda if torch.cuda.is_available() else cpu) model model.to(device) # 将输入数据也移到GPU input_tensor input_tensor.to(device) # 使用半精度浮点数FP16加速 if device.type cuda: model model.half() input_tensor input_tensor.half()5.3 检测结果不准确怎么办问题模型漏检或误检了很多物体。解决方法调整置信度阈值尝试不同的NMS阈值使用更合适的模型版本# 调整参数来优化结果 def optimize_detection(detector, image_path, conf_threshold0.25, # 置信度阈值 iou_threshold0.45): # NMS阈值 # 一些模型支持在推理时传入参数 result detector(image_path, conf_thresholdconf_threshold, iou_thresholdiou_threshold) return result # 尝试不同的参数组合 for conf in [0.1, 0.25, 0.5, 0.75]: for iou in [0.3, 0.45, 0.6]: result optimize_detection(detector, test.jpg, conf, iou) print(fconf{conf}, iou{iou}: 检测到 {len(result[boxes])} 个目标)5.4 如何处理视频或摄像头流问题想用DAMO-YOLO处理视频而不是单张图片。解决方法逐帧处理视频原理和图片一样。def process_video(model, video_path, output_pathoutput_video.mp4): 处理视频文件 # 打开视频 cap cv2.VideoCapture(video_path) # 获取视频信息 fps int(cap.get(cv2.CAP_PROP_FPS)) width int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 创建视频写入器 fourcc cv2.VideoWriter_fourcc(*mp4v) out cv2.VideoWriter(output_path, fourcc, fps, (width, height)) frame_count 0 while True: ret, frame cap.read() if not ret: break # 处理当前帧 # 这里需要将frame转换为模型需要的格式 # 具体转换代码参考前面的图片处理部分 # 绘制检测结果 # ...绘制代码 # 写入输出视频 out.write(frame) frame_count 1 if frame_count % 30 0: print(f已处理 {frame_count} 帧) # 释放资源 cap.release() out.release() cv2.destroyAllWindows() print(f视频处理完成保存到: {output_path})6. 总结通过这篇文章你应该已经掌握了DAMO-YOLO的基本使用方法。我们来回顾一下关键点模型加载可以直接加载本地模型文件也可以使用ModelScope的API后者更简单图片处理需要将图片调整大小、转换为Tensor、进行归一化推理过程使用torch.no_grad()加速注意输入输出的形状后处理包括解析输出、过滤低置信度框、应用NMS、坐标转换结果可视化用OpenCV把检测框画在图片上直观展示结果DAMO-YOLO是一个强大的目标检测工具在实际项目中你可能还需要针对特定场景微调模型优化推理速度以满足实时性要求集成到更大的系统中如监控系统、自动驾驶等最重要的是动手实践。复制文章中的代码用自己的图片试试看遇到问题就查文档、搜错误信息。深度学习开发就是这样一边踩坑一边学习慢慢就熟练了。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。