YOLOv8 OBB win10+ visual 2022移植部署

前言

想做一个目标旋转角度检测的工程,但是网上多少python的,或者linux的。在win10+ visual 2022移植部署,记录一下。
参考 这篇文章没有C++ win10 环境下的部署教程,我相对于是对此做了补充。

1、下载工程

https://github.com/shouxieai/tensorRT_Pro

2 模型导出

  1. 在 ultralytics/engine/exporter.py 文件中改动一处
    在这里插入图片描述
# output_names = ["output0", "output1"] if isinstance(self.model, SegmentationModel) else ["output0"]
# dynamic = self.args.dynamic
# if dynamic:
#     dynamic = {"images": {0: "batch", 2: "height", 3: "width"}}  # shape(1,3,640,640)
#     if isinstance(self.model, SegmentationModel):
#         dynamic["output0"] = {0: "batch", 2: "anchors"}  # shape(1, 116, 8400)
#         dynamic["output1"] = {0: "batch", 2: "mask_height", 3: "mask_width"}  # shape(1,32,160,160)
#     elif isinstance(self.model, DetectionModel):
#         dynamic["output0"] = {0: "batch", 2: "anchors"}  # shape(1, 84, 8400)
# ========== exporter.py ==========
output_names = ['output0', 'output1'] if isinstance(self.model, SegmentationModel) else ['output']
dynamic = self.args.dynamic
if dynamic:
    dynamic = {'images': {0: 'batch'}}  # shape(1,3,640,640)
    if isinstance(self.model, SegmentationModel):
        dynamic['output0'] = {0: 'batch', 2: 'anchors'}  # shape(1, 116, 8400)
        dynamic['output1'] = {0: 'batch', 2: 'mask_height', 3: 'mask_width'}  # shape(1,32,160,160)
    elif isinstance(self.model, DetectionModel):
        dynamic['output'] = {0: 'batch'}  # shape(1, 84, 8400)
  1. 在 ultralytics/nn/modules/head.py 文件中改动一处
    在这里插入图片描述
def forward(self, x):
    """Concatenates and returns predicted bounding boxes and class probabilities."""
    bs = x[0].shape[0]  # batch size
    angle = torch.cat([self.cv4[i](x[i]).view(bs, self.ne, -1) for i in range(self.nl)], 2)  # OBB theta logits
    # NOTE: set `angle` as an attribute so that `decode_bboxes` could use it.
    angle = (angle.sigmoid() - 0.25) * math.pi  # [-pi/4, 3pi/4]
    # angle = angle.sigmoid() * math.pi / 2  # [0, pi/2]
    if not self.training:
        self.angle = angle
    x = Detect.forward(self, x)
    if self.training:
        return x, angle
    #return torch.cat([x, angle], 1) if self.export else (torch.cat([x[0], angle], 1), (x[1], angle))
    return torch.cat([x, angle], 1).permute(0, 2, 1) if self.export else (torch.cat([x[0], angle], 1), (x[1], angle))

在终端执行如下指令即可完成 onnx 导出:

from ultralytics import YOLO

model = YOLO("yolov8_obb_zwc_0918.pt")

success = model.export(format="onnx", dynamic=True, simplify=True)

在这里插入图片描述

3 C++

修改一个简单的测试测序,在原工程app_yolo_obb.cpp 的基础上修改如下

#include "trt_builder.hpp"
#include <trt_infer.hpp>
#include <ilogger.hpp>
#include "yolo_obb.hpp"
static const char* dotalabels[] = {
    "0topleft", "1topright", "2downleft", "3downright", "4top",
    "5right", "6down", "7left", "bridge", "large vehicle",
    "small vehicle", "helicopter", "roundabout", "soccer ball field", "swimming pool"
};
using namespace std;
static vector<cv::Point> xywhr2xyxyxyxy(const YoloOBB::Box& box) {
    float cos_value = std::cos(box.angle);
    float sin_value = std::sin(box.angle);

    float w_2 = box.width / 2, h_2 = box.height / 2;
    float vec1_x = w_2 * cos_value, vec1_y = w_2 * sin_value;
    float vec2_x = -h_2 * sin_value, vec2_y = h_2 * cos_value;

    vector<cv::Point> corners;
    corners.push_back(cv::Point(box.center_x + vec1_x + vec2_x, box.center_y + vec1_y + vec2_y));
    corners.push_back(cv::Point(box.center_x + vec1_x - vec2_x, box.center_y + vec1_y - vec2_y));
    corners.push_back(cv::Point(box.center_x - vec1_x - vec2_x, box.center_y - vec1_y - vec2_y));
    corners.push_back(cv::Point(box.center_x - vec1_x + vec2_x, box.center_y - vec1_y + vec2_y));

    return corners;
}
static void test_single_image() {

    //    //----initial
    auto engine = YoloOBB::create_infer(
        "E:***.trt",            // engine file
        0,                                      // gpu id
        0.25f,                                  // confidence threshold
        0.45f,                                  // nms threshold
        YoloOBB::NMSMethod::FastGPU,            // NMS method, fast GPU / CPU
        1024,                                   // max objects
        false                                   // preprocess use multi stream
    );
    if (engine == nullptr) {
        INFOE("Engine is nullptr");
        return;
    }
    //
    auto files = iLogger::find_files("IMG", "*.jpg;*.jpeg;*.png;*.gif;*.tif");
    vector<cv::Mat> images;
    for (int i = 0; i < files.size(); ++i) {
        auto image = cv::imread(files[i]);
        images.emplace_back(image);
    }
    //for (auto& img : images)
    //{
    //    cv::imshow("src", img);
    //    cv::waitKey(0);
    //}
    for(auto &img:images)
    {
        cv::Mat image=img ;
        if (image.empty()) {
            INFOE("Image is empty");
            return;
        }

        auto boxes = engine->commit(image).get();

        for (auto& obj : boxes) {
            uint8_t b, g, r;
            tie(b, g, r) = iLogger::random_color(obj.class_label);
            auto corners = xywhr2xyxyxyxy(obj);
            cv::polylines(image, vector<vector<cv::Point>>{corners}, true, cv::Scalar(b, g, r), 2, 16);

            auto name = dotalabels[obj.class_label];
            auto caption = iLogger::format("%s %.2f", name, obj.confidence);
            int width = cv::getTextSize(caption, 0, 1, 2, nullptr).width + 10;
            cv::rectangle(image, cv::Point(corners[0].x - 3, corners[0].y - 33), cv::Point(corners[0].x - 3 + width, corners[0].y), cv::Scalar(b, g, r), -1);
            cv::putText(image, caption, cv::Point(corners[0].x - 3, corners[0].y - 5), 0, 1, cv::Scalar::all(0), 2, 16);
        }
        INFO("Save to Result.jpg, %d objects", boxes.size());
        cv::imwrite("Result.jpg", image);
        cv::imshow("result", image);
        cv::waitKey(0);
    }
    engine.reset();  
}
int main() {
    test_single_image();
    return 0;
}

3.1 工程下IMG 文件夹结构(你要测试的图片集合)

在这里插入图片描述

3.2 所需要的CPP

在这里插入图片描述

3.3 编译& 添加头文件

在这里插入图片描述

在这里插入图片描述

3.3 .cu的文件需要设置CUDA C/C++ 编译类型

在这里插入图片描述

4 结果

在这里插入图片描述

在这里插入图片描述

5 PS

Cuda 、cudnn 、OpenCV,的配置可以自行百度or参考我的往期文章https://blog.csdn.net/qq_36784503/article/details/138597169

YOLOv5是一种实时目标检测算法,它是由Ultralytics团队开发的一种基于深度学习的目标检测模型。它的目标是通过输入一张图像,自动识别并定位图像中的各种目标,如人、车、建筑等。 而YOLOv5在Windows 10操作系统上的应用也是非常简单的,只需要按照以下步骤进行操作: 1.环境准备:首先,确保你的电脑已经安装了Python和PyTorch等必要的软件和库。可以在Anaconda官网下载和安装Anaconda,然后使用conda命令安装Python和PyTorch。 2.克隆YOLOv5代码库:使用Git命令,在命令行中输入以下指令,将YOLOv5的代码库克隆到本地。 ``` git clone https://github.com/ultralytics/yolov5.git ``` 3.下载权重文件:在YOLOv5的GitHub页面中,可以找到不同模型的权重文件,根据需要选择下载对应的权重文件。 4.运行检测:在命令行中,进入到克隆的YOLOv5目录下,然后执行以下命令,即可进行目标检测。 ``` python detect.py --weights path/to/weights --source path/to/images ``` 其中,`path/to/weights`是模型的权重文件路径,`path/to/images`是要检测的图像路径。 5.查看检测结果:程序运行完毕后,会在YOLOv5目录下的`runs/detect/exp`文件夹中生成检测结果。你可以通过查看对应文件夹下的图像和标签文件,来了解模型对目标的检测和定位效果。 总之,YOLOv5的在Windows 10上的使用非常方便。你只需按照以上步骤进行操作,就能够轻松地进行目标检测任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值