地平线旭日x3派部署yolov8

news2024/10/5 16:27:21

地平线旭日x3派部署yolov8

  • 总体流程
    • 1.导出onnx模型
      • 导出
      • YOLOV8_onnxruntime.py验证onnx
      • utils.py
    • 2.在开发机转为bin模型
      • 2.1准备数据图片
      • 2.2转换必备的yaml文件
      • 2.3开始转换
    • 3.开发机验证**quantized_model.onnx
    • 4.板子运行bin模型
  • 资源链接

总体流程

1.导出onnx模型

导出

使用yolov8的github库导出onnx模型。注意设置opset为11。

from ultralytics import YOLO
model = YOLO('yolov8s.yaml')
model = YOLO('yolov8s.pt')
# 注意设置opset=11
success = model.export(format='onnx',opset=11)

会在运行目录下生成yolov8s.onnx。

YOLOV8_onnxruntime.py验证onnx

使用YOLOV8_onnxruntime.py验证导出的onnx是否可用。运行正常的话会生成result.jpg,图中有检测出的物体。

import time
import cv2
import numpy as np
import onnxruntime

from utils import xywh2xyxy, nms, draw_detections

class YOLOv8:
    def __init__(self, path, conf_thres=0.7, iou_thres=0.5):
        self.conf_threshold = conf_thres
        self.iou_threshold = iou_thres

        # Initialize model
        self.initialize_model(path)

    def __call__(self, image):
        return self.detect_objects(image)

    def initialize_model(self, path):
        self.session = onnxruntime.InferenceSession(path,
                                                    providers=['CUDAExecutionProvider',
                                                               'CPUExecutionProvider'])
        # Get model info
        self.get_input_details()
        self.get_output_details()


    def detect_objects(self, image):
        input_tensor = self.prepare_input(image)

        # Perform inference on the image
        outputs = self.inference(input_tensor)

        self.boxes, self.scores, self.class_ids = self.process_output(outputs)

        return self.boxes, self.scores, self.class_ids

    def prepare_input(self, image):
        self.img_height, self.img_width = image.shape[:2]

        input_img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

        # Resize input image
        input_img = cv2.resize(input_img, (self.input_width, self.input_height))

        # Scale input pixel values to 0 to 1
        input_img = input_img / 255.0
        input_img = input_img.transpose(2, 0, 1)
        input_tensor = input_img[np.newaxis, :, :, :].astype(np.float32)
        return input_tensor

    def inference(self, input_tensor):
        start = time.perf_counter()
        outputs = self.session.run(self.output_names, {self.input_names[0]: input_tensor})
        print(outputs[0].shape)
        # print(f"Inference time: {(time.perf_counter() - start)*1000:.2f} ms")
        return outputs

    def process_output(self, output):
        predictions = np.squeeze(output[0]).T

        # Filter out object confidence scores below threshold
        scores = np.max(predictions[:, 4:], axis=1)
        predictions = predictions[scores > self.conf_threshold, :]
        scores = scores[scores > self.conf_threshold]

        if len(scores) == 0:
            return [], [], []

        # Get the class with the highest confidence
        class_ids = np.argmax(predictions[:, 4:], axis=1)

        # Get bounding boxes for each object
        boxes = self.extract_boxes(predictions)

        # Apply non-maxima suppression to suppress weak, overlapping bounding boxes
        indices = nms(boxes, scores, self.iou_threshold)
        print("bbox len :",len(indices))
        return boxes[indices], scores[indices], class_ids[indices]

    def extract_boxes(self, predictions):
        # Extract boxes from predictions
        boxes = predictions[:, :4]

        # Scale boxes to original image dimensions
        boxes = self.rescale_boxes(boxes)

        # Convert boxes to xyxy format
        boxes = xywh2xyxy(boxes)
        return boxes

    def rescale_boxes(self, boxes):

        # Rescale boxes to original image dimensions
        input_shape = np.array([self.input_width, self.input_height, self.input_width, self.input_height])
        boxes = np.divide(boxes, input_shape, dtype=np.float32)
        boxes *= np.array([self.img_width, self.img_height, self.img_width, self.img_height])
        return boxes

    def draw_detections(self, image, draw_scores=True, mask_alpha=0.4):

        return draw_detections(image, self.boxes, self.scores,
                               self.class_ids, mask_alpha)

    def get_input_details(self):
        model_inputs = self.session.get_inputs()
        self.input_names = [model_inputs[i].name for i in range(len(model_inputs))]

        self.input_shape = model_inputs[0].shape
        self.input_height = self.input_shape[2]
        self.input_width = self.input_shape[3]

    def get_output_details(self):
        model_outputs = self.session.get_outputs()
        self.output_names = [model_outputs[i].name for i in range(len(model_outputs))]

if __name__ == '__main__':
    model_path = "yolov8s.onnx"
    # model_path = "model_output/horizon_x3_original_float_model.onnx"
    # Initialize YOLOv7 object detector
    yolov8_detector = YOLOv8(model_path, conf_thres=0.5, iou_thres=0.5)

    # img_url = "https://live.staticflickr.com/13/19041780_d6fd803de0_3k.jpg"
    # img = imread_from_url(img_url)
    img = cv2.imread('1121687586719_.pic.jpg')
    # Detect Objects
    yolov8_detector(img)

    # Draw detections
    combined_img = yolov8_detector.draw_detections(img)
    # cv2.namedWindow("Output", cv2.WINDOW_NORMAL)
    # cv2.imshow("Output", combined_img)
    # cv2.waitKey(0)
    cv2.imwrite('result.jpg',combined_img)

YOLOV8_onnxruntime.py 需要导入utils.py,代码如下:

utils.py

import numpy as np
import cv2

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']

# Create a list of colors for each class where each color is a tuple of 3 integer values
rng = np.random.default_rng(3)
colors = rng.uniform(0, 255, size=(len(class_names), 3))


def nms(boxes, scores, iou_threshold):
    # Sort by score
    sorted_indices = np.argsort(scores)[::-1]

    keep_boxes = []
    while sorted_indices.size > 0:
        # Pick the last box
        box_id = sorted_indices[0]
        keep_boxes.append(box_id)

        # Compute IoU of the picked box with the rest
        ious = compute_iou(boxes[box_id, :], boxes[sorted_indices[1:], :])

        # Remove boxes with IoU over the threshold
        keep_indices = np.where(ious < iou_threshold)[0]

        # print(keep_indices.shape, sorted_indices.shape)
        sorted_indices = sorted_indices[keep_indices + 1]

    return keep_boxes


def compute_iou(box, boxes):
    # Compute xmin, ymin, xmax, ymax for both boxes
    xmin = np.maximum(box[0], boxes[:, 0])
    ymin = np.maximum(box[1], boxes[:, 1])
    xmax = np.minimum(box[2], boxes[:, 2])
    ymax = np.minimum(box[3], boxes[:, 3])

    # Compute intersection area
    intersection_area = np.maximum(0, xmax - xmin) * np.maximum(0, ymax - ymin)

    # Compute union area
    box_area = (box[2] - box[0]) * (box[3] - box[1])
    boxes_area = (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])
    union_area = box_area + boxes_area - intersection_area

    # Compute IoU
    iou = intersection_area / union_area

    return iou


def xywh2xyxy(x):
    # Convert bounding box (x, y, w, h) to bounding box (x1, y1, x2, y2)
    y = np.copy(x)
    y[..., 0] = x[..., 0] - x[..., 2] / 2
    y[..., 1] = x[..., 1] - x[..., 3] / 2
    y[..., 2] = x[..., 0] + x[..., 2] / 2
    y[..., 3] = x[..., 1] + x[..., 3] / 2
    return y


def draw_detections(image, boxes, scores, class_ids, mask_alpha=0.3):
    mask_img = image.copy()
    det_img = image.copy()

    img_height, img_width = image.shape[:2]
    size = min([img_height, img_width]) * 0.0006
    text_thickness = int(min([img_height, img_width]) * 0.001)

    # Draw bounding boxes and labels of detections
    for box, score, class_id in zip(boxes, scores, class_ids):
        color = colors[class_id]

        x1, y1, x2, y2 = box.astype(int)

        # Draw rectangle
        cv2.rectangle(det_img, (x1, y1), (x2, y2), color, 2)

        # Draw fill rectangle in mask image
        cv2.rectangle(mask_img, (x1, y1), (x2, y2), color, -1)

        label = class_names[class_id]
        caption = f'{label} {int(score * 100)}%'
        (tw, th), _ = cv2.getTextSize(text=caption, fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                                      fontScale=size, thickness=text_thickness)
        th = int(th * 1.2)

        cv2.rectangle(det_img, (x1, y1),
                      (x1 + tw, y1 - th), color, -1)
        cv2.rectangle(mask_img, (x1, y1),
                      (x1 + tw, y1 - th), color, -1)
        cv2.putText(det_img, caption, (x1, y1),
                    cv2.FONT_HERSHEY_SIMPLEX, size, (255, 255, 255), text_thickness, cv2.LINE_AA)

        cv2.putText(mask_img, caption, (x1, y1),
                    cv2.FONT_HERSHEY_SIMPLEX, size, (255, 255, 255), text_thickness, cv2.LINE_AA)

    return cv2.addWeighted(mask_img, mask_alpha, det_img, 1 - mask_alpha, 0)


def draw_comparison(img1, img2, name1, name2, fontsize=2.6, text_thickness=3):
    (tw, th), _ = cv2.getTextSize(text=name1, fontFace=cv2.FONT_HERSHEY_DUPLEX,
                                  fontScale=fontsize, thickness=text_thickness)
    x1 = img1.shape[1] // 3
    y1 = th
    offset = th // 5
    cv2.rectangle(img1, (x1 - offset * 2, y1 + offset),
                  (x1 + tw + offset * 2, y1 - th - offset), (0, 115, 255), -1)
    cv2.putText(img1, name1,
                (x1, y1),
                cv2.FONT_HERSHEY_DUPLEX, fontsize,
                (255, 255, 255), text_thickness)


    (tw, th), _ = cv2.getTextSize(text=name2, fontFace=cv2.FONT_HERSHEY_DUPLEX,
                                  fontScale=fontsize, thickness=text_thickness)
    x1 = img2.shape[1] // 3
    y1 = th
    offset = th // 5
    cv2.rectangle(img2, (x1 - offset * 2, y1 + offset),
                  (x1 + tw + offset * 2, y1 - th - offset), (94, 23, 235), -1)

    cv2.putText(img2, name2,
                (x1, y1),
                cv2.FONT_HERSHEY_DUPLEX, fontsize,
                (255, 255, 255), text_thickness)

    combined_img = cv2.hconcat([img1, img2])
    if combined_img.shape[1] > 3840:
        combined_img = cv2.resize(combined_img, (3840, 2160))

    return combined_img

2.在开发机转为bin模型

2.1准备数据图片

简单起见,这里直接使用地平线官方教程中的50张rgb格式的示例图片。图片路径是horizon_model_convert_sample/04_detection/03_yolov5s/mapper/calibration_data_rgb_f32。其应当存在于本文4.3列出的文件中。如果不存在,根据4.2用户手册6.2.3.2节生成即可。

2.2转换必备的yaml文件

根据onnx模型量化yaml文件模板修改。这里是我使用yolov8的yaml文件。

# 模型转化相关的参数
model_parameters:
  # 必选参数
  # Onnx浮点网络数据模型文件, 例如:onnx_model: './horizon_x3_onnx.onnx'
  onnx_model: './yolov8s.onnx'
  march: "bernoulli2"
  layer_out_dump: False
  working_dir: 'model_output'
  output_model_file_prefix: 'horizon_x3'

# 模型输入相关参数
input_parameters:
  input_name: ""
  input_shape: ''
  input_type_rt: 'nv12'
  input_layout_rt: 'NHWC'

  # 必选参数
  # 原始浮点模型训练框架中所使用训练的数据类型
  input_type_train: 'rgb'

  # 必选参数
  # 原始浮点模型训练框架中所使用训练的数据排布, 可选值为 NHWC/NCHW
  input_layout_train: 'NCHW'
  
  # 必选参数  
  # 原始浮点模型训练框架中所使用数据预处理方法,可配置
  norm_type: 'data_mean_and_scale'

  # 必选参数
  # 图像减去的均值, 如果是通道均值,value之间必须用空格分隔
  mean_value: 111.0 109.0 118.0 

  # 必选参数
  # 图像预处理缩放比例,如果是通道缩放比例,value之间必须用空格分隔,计算公式:scale = 1/std
  scale_value: 0.0078125 0.001215 0.003680

# 模型量化相关参数
calibration_parameters:
  # 必选参数, 使用2.1中的图片路径
  cal_data_dir: './calibration_data_rgb_f32' 
  cal_data_type: 'float32'
  calibration_type: 'default'
# 编译器相关参数
compiler_parameters:
  compile_mode: 'latency'
  debug: False
  # core_num: 2	
  optimize_level: 'O3'

2.3开始转换

使用docker运行地平线官方给的镜像。根据官方用户手册6.2.2. 环境安装配置环境。转换命令如下。

hb_mapper makertbin --config yolov8_onnx_convert.yaml --model-type onnx

等待运行结束,如下界面表示运行成功。
在这里插入图片描述
在model_output下存放转换后的模型。应当存在四个不同的模型。

  1. ***_original_float_model.onnx
  2. ***_optimized_float_model.onnx
  3. ***_quantized_model.onnx
  4. ***.bin

3.开发机验证**quantized_model.onnx

对于1. ***_original_float_model.onnx
2. ***_optimized_float_model.onnx
3. ***_quantized_model.onnx
都可以使用YOLOv8_hb_onnxruntime.py测试运行。需要注意的是

  1. 对于YOLOv8_hb_onnxruntime来说,需要使用horizon_bpu的环境运行。根据6.2.2. 环境安装可配置horizon_bpu环境。而对于1中的YOLOV8_onnxruntime.py,安装onnxruntime库可运行.
  2. 输入格式。对于optimized_float_model.onnx和original_float_model.onnx,使用NCHW输入格式即可。而对于quantized_model.onnx和***.bin,需要将格式改为NHWC

YOLOv8_hb_onnxruntime.py代码如下。运行成功将生成result.jpg图片。

import time
import cv2
import numpy as np
from horizon_tc_ui import HB_ONNXRuntime

from utils import xywh2xyxy, nms, draw_detections


class YOLOv8:

    def __init__(self, path, conf_thres=0.7, iou_thres=0.5):
        self.conf_threshold = conf_thres
        self.iou_threshold = iou_thres

        # Initialize model
        self.initialize_model(path)

    def __call__(self, image):
        return self.detect_objects(image)

    def initialize_model(self, path):
        
        self.session = HB_ONNXRuntime(model_file=path)
        # self.session.set_dim_param(0, 0, '?')
        # Get model info
        self.get_input_details()
        self.get_output_details()


    def detect_objects(self, image):
        input_tensor = self.prepare_input(image)
        
        # Perform inference on the image
        outputs = self.inference(input_tensor)

        self.boxes, self.scores, self.class_ids = self.process_output(outputs)

        return self.boxes, self.scores, self.class_ids

    def prepare_input(self, image):
        self.img_height, self.img_width = image.shape[:2]
        
        input_img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

        # Resize input image
        input_img = cv2.resize(input_img, (self.input_width, self.input_height))

        # Scale input pixel values to 0 to 1
        # input_img = input_img / 255.0
        # input_img = input_img.transpose(2, 0, 1)
        
        input_tensor = input_img[np.newaxis, :, :, :].astype(np.float32)
        return input_tensor

    def inference(self, input_tensor):
        start = time.perf_counter()
        input_name = self.session.input_names[0]
        output_name = self.session.output_names
        outputs = self.session.run(output_name, {input_name: input_tensor},input_offset=128)
        
        print(outputs[0].shape)
        print(f"Inference time: {(time.perf_counter() - start)*1000:.2f} ms")
        return outputs

    def process_output(self, output):
        predictions = np.squeeze(output[0]).T

        # Filter out object confidence scores below threshold
        scores = np.max(predictions[:, 4:], axis=1)
        predictions = predictions[scores > self.conf_threshold, :]
        scores = scores[scores > self.conf_threshold]

        if len(scores) == 0:
            return [], [], []

        # Get the class with the highest confidence
        class_ids = np.argmax(predictions[:, 4:], axis=1)

        # Get bounding boxes for each object
        boxes = self.extract_boxes(predictions)

        # Apply non-maxima suppression to suppress weak, overlapping bounding boxes
        indices = nms(boxes, scores, self.iou_threshold)
        print("bbox len :",len(indices))
        return boxes[indices], scores[indices], class_ids[indices]

    def extract_boxes(self, predictions):
        # Extract boxes from predictions
        boxes = predictions[:, :4]

        # Scale boxes to original image dimensions
        boxes = self.rescale_boxes(boxes)

        # Convert boxes to xyxy format
        boxes = xywh2xyxy(boxes)

        return boxes

    def rescale_boxes(self, boxes):

        # Rescale boxes to original image dimensions
        input_shape = np.array([self.input_width, self.input_height, self.input_width, self.input_height])
        boxes = np.divide(boxes, input_shape, dtype=np.float32)
        boxes *= np.array([self.img_width, self.img_height, self.img_width, self.img_height])
        return boxes

    def draw_detections(self, image, draw_scores=True, mask_alpha=0.4):

        return draw_detections(image, self.boxes, self.scores,
                               self.class_ids, mask_alpha)

    def get_input_details(self):
        model_inputs = self.session.get_inputs()
        self.input_names = [model_inputs[i].name for i in range(len(model_inputs))]
        
        self.input_shape = model_inputs[0].shape
        
        self.input_height = self.input_shape[1]
        self.input_width = self.input_shape[2]

    def get_output_details(self):
        model_outputs = self.session.get_outputs()
        self.output_names = [model_outputs[i].name for i in range(len(model_outputs))]


if __name__ == '__main__':
    # model_path = "yolov8n.onnx"
    model_path = "model_output/horizon_x3_quantized_model.onnx"
    # Initialize YOLOv7 object detector
    yolov8_detector = YOLOv8(model_path, conf_thres=0.5, iou_thres=0.5)

    # img_url = "https://live.staticflickr.com/13/19041780_d6fd803de0_3k.jpg"
    # img = imread_from_url(img_url)
    img = cv2.imread('1121687586719_.pic.jpg')
    # Detect Objects
    yolov8_detector(img)

    # Draw detections
    combined_img = yolov8_detector.draw_detections(img)
    # cv2.namedWindow("Output", cv2.WINDOW_NORMAL)
    # cv2.imshow("Output", combined_img)
    # cv2.waitKey(0)
    cv2.imwrite('result.jpg',combined_img)

4.板子运行bin模型

将**.bin模型拷贝到板子上,使用yolov8.py脚本运行即可。修改代码中的bin文件路径。使用sudo python3 yolov8.py运行脚本

sudo python3 yolov8.py
import time
import cv2
import numpy as np

from hobot_dnn import pyeasy_dnn as dnn
from utils import xywh2xyxy, nms, draw_detections

class YOLOv8:
    def __init__(self, path, conf_thres=0.7, iou_thres=0.5):
        self.conf_threshold = conf_thres
        self.iou_threshold = iou_thres

        # Initialize model
        self.initialize_model(path)

    def __call__(self, image):
        return self.detect_objects(image)

    def initialize_model(self, path):
        
        self.session = dnn.load(path)
        # self.session.set_dim_param(0, 0, '?')
        # Get model info
        self.get_input_details()
        self.get_output_details()


    def detect_objects(self, image):
        input_tensor = self.prepare_input(image)
        print(input_tensor.shape)
        # Perform inference on the image
        outputs = self.inference(input_tensor)

        self.boxes, self.scores, self.class_ids = self.process_output(outputs)

        return self.boxes, self.scores, self.class_ids

    def prepare_input(self, image):
        # self.img_height, self.img_width = image.shape[:2]
        self.img_height, self.img_width = image.shape[:2]
        input_img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        
        # Resize input image
        input_img = cv2.resize(input_img, (640,640))

        # Scale input pixel values to 0 to 1
        # input_img = input_img / 255.0
        
        height, width = input_img.shape[0], input_img.shape[1]
        area = height * width
        yuv420p = cv2.cvtColor(input_img, cv2.COLOR_BGR2YUV_I420).reshape((area * 3 // 2,))
        y = yuv420p[:area]
        uv_planar = yuv420p[area:].reshape((2, area // 4))
        uv_packed = uv_planar.transpose((1, 0)).reshape((area // 2,))

        nv12 = np.zeros_like(yuv420p)
        nv12[:height * width] = y
        nv12[height * width:] = uv_packed
        return nv12

    def inference(self, input_tensor):
        start = time.perf_counter()
        
        # outputs = self.session.run(output_name, {input_name: input_tensor},input_offset=128)
        outputs = self.session[0].forward(input_tensor)
        
        print(outputs[0].buffer.shape)
        print(f"Inference time: {(time.perf_counter() - start)*1000:.2f} ms")
        return outputs

    def process_output(self, output):
        predictions = np.squeeze(output[0].buffer).T

        # Filter out object confidence scores below threshold
        scores = np.max(predictions[:, 4:], axis=1)
        predictions = predictions[scores > self.conf_threshold, :]
        scores = scores[scores > self.conf_threshold]
        
        
        if len(scores) == 0:
            return [], [], []

        # Get the class with the highest confidence
        class_ids = np.argmax(predictions[:, 4:], axis=1)

        # Get bounding boxes for each object
        boxes = self.extract_boxes(predictions)

        # Apply non-maxima suppression to suppress weak, overlapping bounding boxes
        indices = nms(boxes, scores, self.iou_threshold)
        print("indices len :",len(indices))
        return boxes[indices], scores[indices], class_ids[indices]

    def extract_boxes(self, predictions):
        # Extract boxes from predictions
        boxes = predictions[:, :4]

        # Scale boxes to original image dimensions
        boxes = self.rescale_boxes(boxes)

        # Convert boxes to xyxy format
        boxes = xywh2xyxy(boxes)

        return boxes

    def rescale_boxes(self, boxes):

        # Rescale boxes to original image dimensions
        input_shape = np.array([self.input_width, self.input_height, self.input_width, self.input_height])
        boxes = np.divide(boxes, input_shape, dtype=np.float32)
        boxes *= np.array([self.img_width, self.img_height, self.img_width, self.img_height])
        return boxes

    def draw_detections(self, image, draw_scores=True, mask_alpha=0.4):

        return draw_detections(image, self.boxes, self.scores,
                               self.class_ids, mask_alpha)

    def get_input_details(self):
    
        self.input_height = 640
        self.input_width = 640

    def get_output_details(self):
        pass


if __name__ == '__main__':
    model_path = "/userdata/horizon_x3.bin"
    # Initialize YOLOv7 object detector
    yolov8_detector = YOLOv8(model_path, conf_thres=0.5, iou_thres=0.5)

    # img_url = "https://live.staticflickr.com/13/19041780_d6fd803de0_3k.jpg"
    # img = imread_from_url(img_url)
    img = cv2.imread('WechatIMG112.jpeg')
    # Detect Objects
    yolov8_detector(img)

    # Draw detections
    combined_img = yolov8_detector.draw_detections(img)
    # cv2.namedWindow("Output", cv2.WINDOW_NORMAL)
    # cv2.imshow("Output", combined_img)
    # cv2.waitKey(0)
    cv2.imwrite('result.jpg',combined_img)

yolov8n模型,在板子上运行,延迟为270ms左右。
yolov8s模型,在板子上运行,延迟为370ms左右。

资源链接

1 官网资源中心链接(包括开发者工具、docker镜像等)
2 官方用户手册(包括说明书、环境配置等教程)
3.公版模型转换示例下载。如果有找不到的文件,就去这里面找。

wget -c ftp://xj3ftp@vrftp.horizon.ai/model_convert_sample/horizon_model_convert_sample.tar.gz --ftp-password=xj3ftp@123$%

官方手册中的文件能下都下。官方手册文件变了,很多文件路径对不上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/684069.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

03 | 事务隔离:为什么你改了我还看不见?

以下出自 《MySQL 实战 45 讲》 03 | 事务隔离&#xff1a;为什么你改了我还看不见&#xff1f; 隔离性与隔离级别 当数据库上有多个事务同时执行的时候&#xff0c;就可能出现脏读&#xff08;dirty read&#xff09;、不可重复读&#xff08;non-repeatable read&#xff0…

搜索功能全流程解析

在产品中一般会分布着大大小小的搜索&#xff0c;以便提升用户的信息获取效率和信息消费的能力。本文作者全流程角度&#xff0c;对搜索功能进行了讲解&#xff0c;并从搜索流程中寻找提升体验的触点&#xff0c;一起来看一下吧。 在产品中因多功能诉求和业务复杂性等因素&…

《Pytorch深度学习和图神经网络(卷 1)》学习笔记——第三章

学习基于如下书籍&#xff0c;仅供自己学习&#xff0c;用来记录回顾&#xff0c;非教程。 <PyTorch深度学习和图神经网络&#xff08;卷 1&#xff09;——基础知识>一书配套代码&#xff1a; https://github.com/aianaconda/pytorch-GNN-1st 百度网盘链接&#xff1a;…

vite优化

1.利用 rollup-plugin-analyzer 插件进行进行代码体积分析&#xff0c;从而优化你的代码。 根据项目体积分析&#xff0c;进行接下来的优化&#xff1a; &#xff08;一&#xff09;使用unplugin-vue-components插件按需加载antd vue 组件&#xff1a; 使用步骤 1、安装插件…

6.18 、Java初级:锁

1 同步锁 1.1 前言 经过前面多线程编程的学习,我们遇到了线程安全的相关问题,比如多线程售票情景下的超卖/重卖现象. 上节笔记点这里-进程与线程笔记 我们如何判断程序有没有可能出现线程安全问题,主要有以下三个条件: 在多线程程序中 有共享数据 多条语句操作共享数据 多…

GPT-4 的创造力全方位持平或碾压人类 | 一项最新研究发现

文章目录 一、前言二、主要内容三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 最近&#xff0c;一项有关 GPT-4 的创造力思维测试火了。来自蒙大拿大学和 UM Western 大学的研究团队发现&#xff0c;GPT-4 在 Torrance 创造性思维…

Sharding-JDBC之RangeShardingAlgorithm(范围分片算法)

目录 一、简介二、maven依赖三、数据库3.1、创建数据库3.2、创建表 四、配置&#xff08;二选一&#xff09;4.1、properties配置4.2、yml配置 五、范围分片算法六、实现6.1、实体层6.2、持久层6.3、服务层6.4、测试类6.4.1、保存订单数据6.4.2、根据时间范围查询订单 一、简介…

还在等待本地渲染?云渲染才是真的省时省心又省钱!

可能很多设计师会觉得本地渲染效果图或动画更灵活&#xff0c;而且没有什么额外的附加费用&#xff0c;但其实不然&#xff01;当你面对多个大型或紧急的项目时&#xff0c;本地渲染就“慌”了。 接下来我将全面对比“本地渲染”和“云渲染”&#xff0c;相信还在等待本地渲染…

黑客常用cmd命令(window版)

1、ping命令 ping命令是一个常用的网络工具&#xff0c;用来测试和诊断网络连接状况。通过发送ICMP&#xff08;Internet控制消息协议&#xff09;数据包到目标主机&#xff0c;并接收回复的数据包&#xff0c;可以测量目标主机的可达性、平均响应时间等指标。 在Windows操作…

前后端实现:行为验证码---文字点选

最近接到一个新的需求&#xff0c;由于客户是内网&#xff0c;你能使用腾讯的验证码了&#xff0c;需要改为前后端实现。 具体的代码已经提交git 项目效果图&#xff1a; 使用的技术栈&#xff1a;vitevue3ts git地址&#xff1a;https://github.com/susanliy/point_captcha…

TCP/IP协议是什么?

78. TCP/IP协议是什么&#xff1f; TCP/IP协议是一组用于互联网通信的网络协议&#xff0c;它定义了数据在网络中的传输方式和规则。作为前端工程师&#xff0c;了解TCP/IP协议对于理解网络通信原理和调试网络问题非常重要。本篇文章将介绍TCP/IP协议的概念、主要组成部分和工…

《程序喵》项目跨域问题解决思路

跨域问题&#xff1a;由于浏览器的 同源策略 限制&#xff0c;当一个请求url的协议、域名、端口号三者之间有任意一个与当前的url不同即为跨域。 同源策略是一种约定&#xff0c;它是浏览器中最核心也最基本的安全功能。同源策略会阻止一个域的 Javascript 脚本和另一个域的内…

举例说明梯度下降算法与最小二乘法的区别

梯度下降算法和最小二乘法都是用于求解线性回归问题中参数的优化方法。我们可以通过一个简单的例子来说明它们之间的区别。 假设我们有以下数据点&#xff1a;(1, 2)&#xff0c;(2, 3)&#xff0c;(3, 4)&#xff0c;(4, 5)&#xff0c;我们希望找到一条最佳拟合线 y wx b&a…

Android 中Looper机制详解

版本基于&#xff1a;Android R 0. 前言 在《Android 基于Handler 剖析消息机制》一文中&#xff0c;以 Handler 类为起点详细分析了异步通信&#xff0c;分析了Java 端 Handler 与Looper、MessageQueue、Message 之前的通信关系。 框架如下&#xff1a; 在Java 端的 Looper …

2. IO 流原理及流的分类

2.1 Java IO 原理 • Java 程序中&#xff0c;对于数据的输入/输出操作以“流(stream)” 的方式进行&#xff0c;可以看做是一种数据的流动。 • I/O 流中的 I/O 是 Input/Output 的缩写&#xff0c; I/O 技术是非常实用的技术&#xff0c;用于处理设备之间的数据传输。如读/写…

浅谈 Cache

1. Cache的历史 在科研领域&#xff0c;C. J. Conti等人于1968年在描述360/85和360/91系统性能差异时最早引入了高速缓存&#xff08;cache&#xff09;一词。Alan Jay Smith于1982年的一篇论文中引入了空间局部性和时间局部性的概念。 Mark Hill在1987年发明了3C&#xff08…

OpenCV项目开发实战--实现平均脸功能教程附(C++/Python)源码实现

文末附基于Python和C++两种方式实现的测试代码下载链接 图 1:计算生成的平均脸 介绍 在本教程中,我们将学习如何使用 OpenCV (C++ / Python) 创建平均面孔。 大多数人会同意图 1 中的女人很漂亮。你能猜出她的种族吗?为什么她的皮肤完美无瑕?好吧,她不是真的。她也不是完…

如何识别手写笔记?这些方法助你快速制作电子版笔记

小张是一名大学生&#xff0c;每天需要上多门课程&#xff0c;整理笔记就成了他不得不常常面对的事情&#xff0c;但是&#xff0c;手写笔记管理起来也有些麻烦&#xff0c;有时候还容易丢失。所以在朋友的推荐下&#xff0c;他使用了一款识别软件并将手写笔记转化为可编辑的电…

推荐好用的AI工具集

AI技术未来已来&#xff0c;我们要拥抱变化 &#xff0c;笔记试用好用AI工具&#xff0c;也在代码中试用chatGPT 一、工具集 解决任何问题&#xff1a;ChatGPT 写文案&#xff1a;Jasper Al 、Copysmith 生成真人视频&#xff1a;Synthesia、 CogView2 AI AI 解决法律问题…

如何对加密字段进行模糊查询

当我们在日常开发中设置数据表时&#xff0c;经常需要定义一些敏感字段&#xff0c;如&#xff1a;身份证号、手机号、住址、账号密码等信息&#xff0c;对待这些敏感信息&#xff0c;我们必须进行加密存储&#xff0c;以保证数据存储安全。但是&#xff0c;当用户查询个人信息…