心路历程(可略过)
为了能在arm64上跑通yolov8,我试过很多很多代码,太多对库版本的要求太高了;
比如说有一个是需要依赖onnx库的,(https://github.com/UNeedCryDear/yolov8-opencv-onnxruntime-cpp)
运行成功了报错error: IOrtSessionOptionsAppendExecutionProvider CUDA’ was not declare
d in this scope,一查是不仅需要onnx库,还需要gpu版本的onnx库
因为这个函数是onnxgpu里才有的函数OrtStatus* status = OrtSessionOptionsAppendExecutionProvider_CUDA(_OrtSessionOptions, cudaID);
而onnxruntime的官方下载地址(https://github.com/microsoft/onnxruntime/releases/)
只有这个版本可以用,但是这个并不是onnxruntime的gpu版本,我在论坛上上搜到onnx官方是不提供nvidia gpu的库的,所以需要自己编译。
我就尝试自己编译,结果有各种各样的版本不匹配的问题,先是说opencv版本低,然后又是杂七杂八的。我都按照要求升级了,最后来一个gcc版本也得升级,那我真是得放弃了,因为当前硬件得这些基础环境是不能改变的,我只能放弃上面这个关于onnxruntime的yolov8代码;(所以得到一个经验,这种大型的库最好直接下载官方现成的,自己编译真的非常麻烦,不到万不得已的时候建议直接换代码,这种版本匹配与编译的问题是最难解决的)
好在很幸运,找到了一个轻量级的能在nvidia arm64硬件上成功运行的轻量级c++yolov8代码,非常简洁好用,不需要依赖杂七杂八的库,可以说直接用jetpack默认的库就能可以简单编译而成,能找到非常不容易,下面是全部代码。
-
jetpack版本
-
文件结构
-
main.cpp
//
// Created by triple-Mu on 24-1-2023.
// Modified by Q-engineering on 6-3-2024
//
#include "chrono"
#include "opencv2/opencv.hpp"
#include "yolov8.hpp"
using namespace std;
using namespace cv;
//#define VIDEO
cv::Size im_size(640, 640);
const int num_labels = 80;
const int topk = 100;
const float score_thres = 0.25f;
const float iou_thres = 0.65f;
int main(int argc, char** argv)
{
float f;
float FPS[16];
int i, Fcnt=0;
cv::Mat image;
std::chrono::steady_clock::time_point Tbegin, Tend;
if (argc < 3) {
fprintf(stderr,"Usage: ./YoloV8_RT [model_trt.engine] [image or video path] \n");
return -1;
}
const string engine_file_path = argv[1];
const string imagepath = argv[2];
for(i=0;i<16;i++) FPS[i]=0.0;
cout << "Set CUDA...\n" << endl;
//wjp
// cudaSetDevice(0);
cudaStream_t(0);
cout << "Loading TensorRT model " << engine_file_path << endl;
cout << "\nWait a second...." << std::flush;
auto yolov8 = new YOLOv8(engine_file_path);
cout << "\rLoading the pipe... " << string(10, ' ')<< "\n\r" ;
cout << endl;
yolov8->MakePipe(true);
#ifdef VIDEO
VideoCapture cap(imagepath);
if (!cap.isOpened()) {
cerr << "ERROR: Unable to open the stream " << imagepath << endl;
return 0;
}
#endif // VIDEO
while(1){
#ifdef VIDEO
cap >> image;
if (image.empty()) {
cerr << "ERROR: Unable to grab from the camera" << endl;
break;
}
#else
image = cv::imread(imagepath);
#endif
yolov8->CopyFromMat(image, im_size);
std::vector<Object> objs;
Tbegin = std::chrono::steady_clock::now();
yolov8->Infer();
Tend = std::chrono::steady_clock::now();
yolov8->PostProcess(objs, score_thres, iou_thres, topk, num_labels);
yolov8->DrawObjects(image, objs);
//calculate frame rate
f = std::chrono::duration_cast <std::chrono::milliseconds> (Tend - Tbegin).count();
cout << "Infer time " << f << endl;
if(f>0.0) FPS[((Fcnt++)&0x0F)]=1000.0/f;
for(f=0.0, i=0;i<16;i++){
f+=FPS[i]; }
putText(image, cv::format("FPS %0.2f", f/16),cv::Point(10,20),cv::FONT_HERSHEY_SIMPLEX,0.6, cv::Scalar(0, 0, 255));
//show output
// imshow("Jetson Orin Nano- 8 Mb RAM", image);
// char esc = cv::waitKey(1);
// if(esc == 27) break;
imwrite("./out.jpg", image);
return 0;
}
cv::destroyAllWindows();
delete yolov8;
return 0;
}
- yolov8.cpp
//
// Created by triple-Mu on 24-1-2023.
// Modified by Q-engineering on 6-3-2024
//
#include "yolov8.hpp"
#include <cuda_runtime_api.h>
#include <cuda.h>
//----------------------------------------------------------------------------------------
//using namespace det;
//----------------------------------------------------------------------------------------
const char* 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"