yolox 推理openvino與c++支持
YOLOX模型ONNX格式說明
我記得大概是在去年七月份的時候我寫過一篇文章是介紹YOLOX+OpenVINO推理的,下載YOLOX的ONNX格式模型(github上可以下載)
https://github.com/Megvii-BaseDetection/YOLOX/tree/main/demo/ONNXRuntime
https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_s.onnx
下載ONNX格式模型,打開之后如圖:
輸入格式:1x3x640x640,默認BGR,無需歸一化。
輸出格式:1x8400x85
01
什么是85
其中85的前四個是cx、cy、w、h大小,第五個是object預測得分,后面80個是COCO類別。
02
什么是8400
模型在數據輸入端幾乎與YOLOv5的代碼一致,沒有什么特別之處,唯一不同的在于輸出層的解析,是把三個不同的輸出層合并在一個里面了,分別是80x80, 40x40, 20x20, 每個特征點預測,所以總數才會是80x80+40x40+20x20 =8400
03
輸出層解析解密
最后一層輸出,這點跟YOLOv5最新版本輸出層有點相似,但是YOLOv5的輸出層更近一步,已經計算了相關的矩形框位置信息,直接輸出就是絕對位置信息,而YOLOX還是輸出原始的相對位置信息,需要解析一波才行(跟最新的YOLOv5相同),說明YOLOX的工程化方面還有待提升!不是開源就完事了!
OpenVINO推理解析
必須說明一點,參考了官方的部分代碼,然后在上面猛改一通(原因是官方代碼寫的不是很好),改完之后,封裝成一個類了,主要的方法跟我封裝的YOLOv5的推理類相似,導出了兩個函數方法
void YOLOXDetector::string onnxpath, float nms, float score)
該方法表示初始化IE,然后加載模型,設置nms閾值與置信度閾值score,創建一個推理請求,同時初始化每一層上對應每個特征點尺度比率。這部分的代碼如下:
voidYOLOXDetector::initConfig(std::stringonnxpath,floatnms,floatscore){
this->nms_threshold=nms;
this->score_threshold=score;
Coreie;
CNNNetworknetwork=ie.ReadNetwork(onnxpath);
InputInfo::Ptrinput_info=network.getInputsInfo().begin()->second;
this->input_name=network.getInputsInfo().begin()->first;
DataPtroutput_info=network.getOutputsInfo().begin()->second;
this->out_name=network.getOutputsInfo().begin()->first;
output_info->setPrecision(Precision::FP32);
ExecutableNetworkexecutable_network=ie.LoadNetwork(network,"CPU");
this->infer_request=executable_network.CreateInferRequest();
std::vector<int>strides={8,16,32};
generate_grids_and_stride(INPUT_W,INPUT_H,strides,grid_strides);
}
檢測函數
void detect(cv::Mat & frame, std::vector&results);
該方法完成檢測,并把檢測結果作為resulte返回,相關的代碼實現可以參考之前的文章,感覺并沒有什么不同,其中最大的不同的地方是對輸出結果的解析,這邊代碼作為單獨的方法函數實現如下(參考官方):
voidYOLOXDetector::generate_yolox_proposals(std::vectorgrid_strides,constfloat*feat_ptr,floatprob_threshold,std::vector&objects)
{
constintnum_anchors=grid_strides.size();
for(intanchor_idx=0;anchor_idxconstintgrid0=grid_strides[anchor_idx].grid0;
constintgrid1=grid_strides[anchor_idx].grid1;
constintstride=grid_strides[anchor_idx].stride;
constintbasic_pos=anchor_idx*(NUM_CLASSES+5);
//yolox/models/yolo_head.pydecodelogic
floatx_center=(feat_ptr[basic_pos+0]+grid0)*stride;
floaty_center=(feat_ptr[basic_pos+1]+grid1)*stride;
floatw=exp(feat_ptr[basic_pos+2])*stride;
floath=exp(feat_ptr[basic_pos+3])*stride;
floatx0=x_center-w*0.5f;
floaty0=y_center-h*0.5f;
floatbox_objectness=feat_ptr[basic_pos+4];
for(intclass_idx=0;class_idxfloatbox_cls_score=feat_ptr[basic_pos+5+class_idx];
floatbox_prob=box_objectness*box_cls_score;
if(box_prob>prob_threshold)
{
DetectResultobj;
obj.box.x=x0;
obj.box.y=y0;
obj.box.width=w;
obj.box.height=h;
obj.classId=class_idx;
obj.score=box_prob;
objects.push_back(obj);
}
}
}
}
最終調用該類實現推理就顯得特別簡單,對圖像跟視頻都是一樣,使用下面的代碼:
detector->initConfig(this->settings->getOnnxModelPath(),score,conf);
std::vectorresults;
detector->detect(frame,results);
最后我發現在onnxruntime上面也一樣可以,基本上重用了大部分的代碼,然后把它們與我之前寫YOLOv5+QT的演示整合了一下,這樣就變成YOLOv5+YOLOx支持OpenVINO/ONNXRUNTIME全部可行的推理,可以自由的通過界面切換!
運行結果如下(請允許我show一下界面):
掃碼查看OpenCV+Pytorch系統化學習路線圖
原文標題:OpenVINO +YOLOX最新版本推理演示
文章出處:【微信公眾號:OpenCV學堂】歡迎添加關注!文章轉載請注明出處。
-
格式
+關注
關注
0文章
23瀏覽量
16886 -
模型
+關注
關注
1文章
3243瀏覽量
48840 -
推理
+關注
關注
0文章
8瀏覽量
7268
發布評論請先 登錄
相關推薦
評論