# 导入代码依赖
import cv2
import numpy as np
import ipywidgets as widgets
from IPython.display import display
import torch
from skvideo.io import vreader, FFmpegWriter
import IPython.display
from ais_bench.infer.interface import InferSession
# import matplotlib.pyplot as plt
from det_utils import letterbox, scale_coords, nms
def preprocess_image(image, cfg, bgr2rgb=True):
"""图片预处理"""
img, scale_ratio, pad_size = letterbox(image, new_shape=cfg['input_shape'])
if bgr2rgb:
img = img[:, :, ::-1]
img = img.transpose(2, 0, 1) # HWC2CHW
img = np.ascontiguousarray(img, dtype=np.float16)/255.0
return img, scale_ratio, pad_size
def draw_bbox(bbox, img0, color, wt, names):
"""在图片上画预测框"""
det_result_str = ''
# 打印标签字典及对应的置信度
print("标签字典中的内容及置信度:")
for class_id, label in names.items():
print(f"标签 ID: {class_id}, 标签名称: {label}, 置信度: 未知(因模型可能没有提供具体置信度)")
# 处理每个检测框
for idx, class_id in enumerate(bbox[:, 5]):
print(f"Class ID: {class_id}, Confidence: {bbox[idx][4]}") # 打印类别 ID 和置信度
# 查找标签字典并打印
if int(class_id) not in names:
print(f"Warning: Class ID {class_id} not found in names.")
continue # 如果没有找到对应的标签,则跳过当前框
img0 = cv2.rectangle(img0, (int(bbox[idx][0]), int(bbox[idx][1])), (int(bbox[idx][2]), int(bbox[idx][3])),
color, wt)
img0 = cv2.putText(img0, str(idx) + ' ' + names[int(class_id)], (int(bbox[idx][0]), int(bbox[idx][1] + 16)),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
img0 = cv2.putText(img0, '{:.4f}'.format(bbox[idx][4]), (int(bbox[idx][0]), int(bbox[idx][1] + 32)),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
det_result_str += '{} {} {} {} {} {}\n'.format(
names[bbox[idx][5]], str(bbox[idx][4]), bbox[idx][0], bbox[idx][1], bbox[idx][2], bbox[idx][3])
return img0
def get_labels_from_txt(path):
"""从txt文件获取图片标签"""
labels_dict = dict()
with open(path) as f:
for cat_id, label in enumerate(f.readlines()):
labels_dict[cat_id] = label.strip()
return labels_dict
def draw_prediction(pred, image, labels):
"""在图片上画出预测框并进行可视化展示"""
imgbox = widgets.Image(format='jpg', height=720, width=1280)
img_dw = draw_bbox(pred, image, (0, 255, 0), 2, labels)
imgbox.value = cv2.imencode('.jpg', img_dw)[1].tobytes()
display(imgbox)
import os
def infer_image(img_path, model, class_names, cfg):
"""图片推理"""
# 图片载入
image = cv2.imread(img_path)
# 数据预处理
img, scale_ratio, pad_size = preprocess_image(image, cfg)
# 模型推理
output = model.infer([img])[0]
output = torch.tensor(output)
# 非极大值抑制后处理
boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"])
pred_all = boxout[0].numpy()
# 预测坐标转换
scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size))
# 图片预测结果可视化
draw_prediction(pred_all, image, class_names)
# 保存结果
output_path = "/home/HwHiAiUser/samples/notebooks/yolov11/output/result.jpg" # 保存结果的文件名
cv2.imwrite(output_path, image) # 保存绘制了预测结果的图像
print(f"推理结果已保存到: {os.path.abspath(output_path)}")
def infer_frame_with_vis(image, model, labels_dict, cfg, bgr2rgb=True):
# 数据预处理
img, scale_ratio, pad_size = preprocess_image(image, cfg, bgr2rgb)
# 模型推理
output = model.infer([img])[0]
output = torch.tensor(output)
# 非极大值抑制后处理
boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"])
pred_all = boxout[0].numpy()
# 预测坐标转换
scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size))
# 图片预测结果可视化
img_vis = draw_bbox(pred_all, image, (0, 255, 0), 2, labels_dict)
return img_vis
def img2bytes(image):
"""将图片转换为字节码"""
return bytes(cv2.imencode('.jpg', image)[1])
def infer_video(video_path, model, labels_dict, cfg):
"""视频推理"""
image_widget = widgets.Image(format='jpeg', width=800, height=600)
display(image_widget)
# 读入视频
cap = cv2.VideoCapture(video_path)
while True:
ret, img_frame = cap.read()
if not ret:
break
# 对视频帧进行推理
image_pred = infer_frame_with_vis(img_frame, model, labels_dict, cfg, bgr2rgb=True)
image_widget.value = img2bytes(image_pred)
def infer_camera(model, labels_dict, cfg):
"""外设摄像头实时推理"""
def find_camera_index():
max_index_to_check = 10 # Maximum index to check for camera
for index in range(max_index_to_check):
cap = cv2.VideoCapture(index)
if cap.read()[0]:
cap.release()
return index
# If no camera is found
raise ValueError("No camera found.")
# 获取摄像头
camera_index = find_camera_index()
cap = cv2.VideoCapture(camera_index)
# 初始化可视化对象
image_widget = widgets.Image(format='jpeg', width=1280, height=720)
display(image_widget)
while True:
# 对摄像头每一帧进行推理和可视化
_, img_frame = cap.read()
image_pred = infer_frame_with_vis(img_frame, model, labels_dict, cfg)
image_widget.value = img2bytes(image_pred)
cfg = {
'conf_thres': 0.4, # 模型置信度阈值,阈值越低,得到的预测框越多
'iou_thres': 0.5, # IOU阈值,高于这个阈值的重叠预测框会被过滤掉
'input_shape': [640, 640], # 模型输入尺寸
}
model_path = '/home/HwHiAiUser/samples/notebooks/yolov11/models/mymodel.om'
label_path = '/home/HwHiAiUser/samples/notebooks/yolov11/models/name.txt'
# 初始化推理模型
model = InferSession(0, model_path)
labels_dict = get_labels_from_txt(label_path)
infer_mode = 'image'
if infer_mode == 'image':
img_path = '/home/HwHiAiUser/samples/notebooks/yolov11/input/2.jpg'
infer_image(img_path, model, labels_dict, cfg)
elif infer_mode == 'camera':
infer_camera(model, labels_dict, cfg)
elif infer_mode == 'video':
video_path = 'racing.mp4'
infer_video(video_path, model, labels_dict, cfg)
使用的设备:Atlas 200I DK A2开发者套件
ATC转换指令:atc --model=best.onnx --framework=5 --output=model --input_format=NCHW --input_shape="images:1,3,640,640" --input_fp16_nodes=images --log=error --soc_version=Ascend310B4
我的推理代码用的是开发板自带的yolov5官方样例,并没有做过多修改,只是把将img = np.ascontiguousarray(img, dtype=np.float32)改为img = np.ascontiguousarray(img, dtype=np.float16)/255.0。网址参考这篇文章https://blog.csdn.net/weixin_44354614/article/details/135368091?spm=1001.2014.3001.5501
论坛中https://www.hiascend.com/forum/thread-0225144681715066110-1-1.html 这篇帖子和我遇到了同样类型的报错,但我并未找到相应的解决办法
模型能够正常加载,但是推理出来的标签并不是我的字典当中的。我的模型只有piaoyang和rice两类,但报错信息如下:
(base) root@davinci-mini:/home/HwHiAiUser/samples/notebooks# /usr/local/miniconda3/bin/python /home/HwHiAiUser/samples/notebooks/yolov11/test3.py /usr/local/miniconda3/lib/python3.9/site-packages/torchvision/io/image.py:13: UserWarning: Failed to load image Python extension:
warn(f"Failed to load image Python extension: {e}") [INFO] acl init success
[INFO] open device 0 success
[INFO] load model /home/HwHiAiUser/samples/notebooks/yolov11/models/mymodel.om success
[INFO] create model description success
标签字典中的内容及置信度:
标签 ID: 0, 标签名称: piaoyang, 置信度: 未知(因模型可能没有提供具体置信度)
标签 ID: 1, 标签名称: rice, 置信度: 未知(因模型可能没有提供具体置信度)
Class ID: 8025.0, Confidence: 45950.25
Warning: Class ID 8025.0 not found in names.
Class ID: 554.0, Confidence: 23852.1875
Warning: Class ID 554.0 not found in names.
Class ID: 8167.0, Confidence: 5878.857421875
Warning: Class ID 8167.0 not found in names.
Class ID: 8391.0, Confidence: 4428.810546875
Warning: Class ID 8391.0 not found in names.
Image(value=b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x02\x01\x01\x01\x01\x01\x02\x01\x01\x01\x02\x02\x02\x02\x02...', format='jpg', height='720', width='1280')
推理结果已保存到: /home/HwHiAiUser/samples/notebooks/yolov11/output/result.jpg
[INFO] unload model success, model Id is 1
[INFO] end to destroy context
[INFO] end to reset device is 0
[INFO] end to finalize acl
推理代码:
# 导入代码依赖 import cv2 import numpy as np import ipywidgets as widgets from IPython.display import display import torch from skvideo.io import vreader, FFmpegWriter import IPython.display from ais_bench.infer.interface import InferSession # import matplotlib.pyplot as plt from det_utils import letterbox, scale_coords, nms def preprocess_image(image, cfg, bgr2rgb=True): """图片预处理""" img, scale_ratio, pad_size = letterbox(image, new_shape=cfg['input_shape']) if bgr2rgb: img = img[:, :, ::-1] img = img.transpose(2, 0, 1) # HWC2CHW img = np.ascontiguousarray(img, dtype=np.float16)/255.0 return img, scale_ratio, pad_size def draw_bbox(bbox, img0, color, wt, names): """在图片上画预测框""" det_result_str = '' # 打印标签字典及对应的置信度 print("标签字典中的内容及置信度:") for class_id, label in names.items(): print(f"标签 ID: {class_id}, 标签名称: {label}, 置信度: 未知(因模型可能没有提供具体置信度)") # 处理每个检测框 for idx, class_id in enumerate(bbox[:, 5]): print(f"Class ID: {class_id}, Confidence: {bbox[idx][4]}") # 打印类别 ID 和置信度 # 查找标签字典并打印 if int(class_id) not in names: print(f"Warning: Class ID {class_id} not found in names.") continue # 如果没有找到对应的标签,则跳过当前框 img0 = cv2.rectangle(img0, (int(bbox[idx][0]), int(bbox[idx][1])), (int(bbox[idx][2]), int(bbox[idx][3])), color, wt) img0 = cv2.putText(img0, str(idx) + ' ' + names[int(class_id)], (int(bbox[idx][0]), int(bbox[idx][1] + 16)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) img0 = cv2.putText(img0, '{:.4f}'.format(bbox[idx][4]), (int(bbox[idx][0]), int(bbox[idx][1] + 32)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) det_result_str += '{} {} {} {} {} {}\n'.format( names[bbox[idx][5]], str(bbox[idx][4]), bbox[idx][0], bbox[idx][1], bbox[idx][2], bbox[idx][3]) return img0 def get_labels_from_txt(path): """从txt文件获取图片标签""" labels_dict = dict() with open(path) as f: for cat_id, label in enumerate(f.readlines()): labels_dict[cat_id] = label.strip() return labels_dict def draw_prediction(pred, image, labels): """在图片上画出预测框并进行可视化展示""" imgbox = widgets.Image(format='jpg', height=720, width=1280) img_dw = draw_bbox(pred, image, (0, 255, 0), 2, labels) imgbox.value = cv2.imencode('.jpg', img_dw)[1].tobytes() display(imgbox) import os def infer_image(img_path, model, class_names, cfg): """图片推理""" # 图片载入 image = cv2.imread(img_path) # 数据预处理 img, scale_ratio, pad_size = preprocess_image(image, cfg) # 模型推理 output = model.infer([img])[0] output = torch.tensor(output) # 非极大值抑制后处理 boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"]) pred_all = boxout[0].numpy() # 预测坐标转换 scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size)) # 图片预测结果可视化 draw_prediction(pred_all, image, class_names) # 保存结果 output_path = "/home/HwHiAiUser/samples/notebooks/yolov11/output/result.jpg" # 保存结果的文件名 cv2.imwrite(output_path, image) # 保存绘制了预测结果的图像 print(f"推理结果已保存到: {os.path.abspath(output_path)}") def infer_frame_with_vis(image, model, labels_dict, cfg, bgr2rgb=True): # 数据预处理 img, scale_ratio, pad_size = preprocess_image(image, cfg, bgr2rgb) # 模型推理 output = model.infer([img])[0] output = torch.tensor(output) # 非极大值抑制后处理 boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"]) pred_all = boxout[0].numpy() # 预测坐标转换 scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size)) # 图片预测结果可视化 img_vis = draw_bbox(pred_all, image, (0, 255, 0), 2, labels_dict) return img_vis def img2bytes(image): """将图片转换为字节码""" return bytes(cv2.imencode('.jpg', image)[1]) def infer_video(video_path, model, labels_dict, cfg): """视频推理""" image_widget = widgets.Image(format='jpeg', width=800, height=600) display(image_widget) # 读入视频 cap = cv2.VideoCapture(video_path) while True: ret, img_frame = cap.read() if not ret: break # 对视频帧进行推理 image_pred = infer_frame_with_vis(img_frame, model, labels_dict, cfg, bgr2rgb=True) image_widget.value = img2bytes(image_pred) def infer_camera(model, labels_dict, cfg): """外设摄像头实时推理""" def find_camera_index(): max_index_to_check = 10 # Maximum index to check for camera for index in range(max_index_to_check): cap = cv2.VideoCapture(index) if cap.read()[0]: cap.release() return index # If no camera is found raise ValueError("No camera found.") # 获取摄像头 camera_index = find_camera_index() cap = cv2.VideoCapture(camera_index) # 初始化可视化对象 image_widget = widgets.Image(format='jpeg', width=1280, height=720) display(image_widget) while True: # 对摄像头每一帧进行推理和可视化 _, img_frame = cap.read() image_pred = infer_frame_with_vis(img_frame, model, labels_dict, cfg) image_widget.value = img2bytes(image_pred) cfg = { 'conf_thres': 0.4, # 模型置信度阈值,阈值越低,得到的预测框越多 'iou_thres': 0.5, # IOU阈值,高于这个阈值的重叠预测框会被过滤掉 'input_shape': [640, 640], # 模型输入尺寸 } model_path = '/home/HwHiAiUser/samples/notebooks/yolov11/models/mymodel.om' label_path = '/home/HwHiAiUser/samples/notebooks/yolov11/models/name.txt' # 初始化推理模型 model = InferSession(0, model_path) labels_dict = get_labels_from_txt(label_path) infer_mode = 'image' if infer_mode == 'image': img_path = '/home/HwHiAiUser/samples/notebooks/yolov11/input/2.jpg' infer_image(img_path, model, labels_dict, cfg) elif infer_mode == 'camera': infer_camera(model, labels_dict, cfg) elif infer_mode == 'video': video_path = 'racing.mp4' infer_video(video_path, model, labels_dict, cfg)