基本思想:项目需要一个TensorRT的检测人属性的模型,随手搜了一个,转了一下,比较简单,部署tensorRT平台上,然后集成到单目3d目标检测上面
测试图片,实验模型链接: /s/1h06cSe-_2zOngViC6lMr4w?pwd=mwh1 提取码: mwh1
一、下载源码和测试
ubuntu@ubuntu:~$ pip3 install paddleclasubuntu@ubuntu:~$ python3 -m pip install paddlepaddle-gpu -i /pypi/simpleubuntu@ubuntu:~$ paddleclas --model_name=person_attribute --infer_imgs=/home/ubuntu/PaddleClas/deploy/images/Pedestrain_Attr.jpg[/07/20 12:34:28] ppcls INFO: attributes: ['Male', 'Age18-60', 'Front', 'Glasses: True', 'Hat: False', 'HoldObjectsInFront: False', 'No bag', 'Upper: LongSleeve UpperPlaid', 'Lower: Trousers', 'No boots'], output: [0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0], filename: /home/ubuntu/PaddleClas/deploy/images/Pedestrain_Attr.jpg[/07/20 12:34:28] ppcls INFO: Predict complete!ubuntu@ubuntu:~$ git clone /PaddlePaddle/PaddleClasCloning into 'PaddleClas'...remote: Enumerating objects: 44667, done.remote: Counting objects: 100% (1916/1916), done.remote: Compressing objects: 100% (518/518), done.Receiving objects: 16% (7472/44667), 106.19 MiB | 500.00 KiB/sremote: Total 44667 (delta 1427), reused 1781 (delta 1387), pack-reused 42751Receiving objects: 100% (44667/44667), 213.46 MiB | 634.00 KiB/s, done.Resolving deltas: 100% (31867/31867), done.ubuntu@ubuntu:~/PaddleClas/deploy/models$ wget https://paddleclas./models/PULC/person_attribute_infer.tar && tar -xf person_attribute_infer.tarubuntu@ubuntu:~/PaddleClas/deploy$ python3 python/predict_cls.py -c configs/PULC/person_attribute/inference_person_attribute.yaml -o Global.use_gpu=True090004.jpg: {'attributes': ['Male', 'Age18-60', 'Back', 'Glasses: False', 'Hat: False', 'HoldObjectsInFront: False', 'Backpack', 'Upper: LongSleeve UpperPlaid', 'Lower: Trousers', 'No boots'], 'output': [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1]}
二、测试和转模型paddle2onnnx.py
ubuntu@ubuntu:~/PaddleClas/deploy$ pip install paddle2onnxubuntu@ubuntu:~/PaddleClas/deploy$ paddle2onnx --model_dir models/person_attribute_infer --model_filename inference.pdmodel --params_filename inference.pdiparams --save_file model.onnx --enable_dev_version True[Paddle2ONNX] Start to parse PaddlePaddle model...[Paddle2ONNX] Model file path: models/person_attribute_infer/inference.pdmodel[Paddle2ONNX] Paramters file path: models/person_attribute_infer/inference.pdiparams[Paddle2ONNX] Start to parsing Paddle model...[Paddle2ONNX] Use opset_version = 9 for ONNX export.[Paddle2ONNX] PaddlePaddle model is exported as ONNX format now.-07-20 12:29:02 [INFO]===============Make PaddlePaddle Better!================-07-20 12:29:02 [INFO]A little survey: /?code=r8hu2s
三、onnx结果测试结果正确
import onnxruntime as ortimport numpy as npimport cv2#outcome listage_list = ['AgeLess18', 'Age18-60', 'AgeOver60']direct_list = ['Front', 'Side', 'Back']bag_list = ['HandBag', 'ShoulderBag', 'Backpack']upper_list = ['UpperStride', 'UpperLogo', 'UpperPlaid', 'UpperSplice']lower_list = ['LowerStripe', 'LowerPattern', 'LongCoat', 'Trousers', 'Shorts','Skirt&Dress']#preprocessdef preproc(img, input_size):img = img[:, :, ::-1] #BGR to RGBimg = cv2.resize(img, input_size,interpolation=1) #unified resizemean = [0.485, 0.456, 0.406]std = [0.229, 0.224, 0.225]mean = np.array(mean).reshape((1, 1, 3)).astype('float32') #broadcaststd = np.array(std).reshape((1, 1, 3)).astype('float32') #broadcastimg = (img.astype('float32') * np.float32(1.0/255.0) - mean) / std #normalize scale:1.0/255.0img = img.transpose(2, 0, 1).astype('float32') #whc to chwreturn imgx = cv2.imread('/home/ubuntu/PaddleClas/deploy/images/Pedestrain_Attr.jpg') #input 53x163 jpgx = preproc(x, (192,256)) #w,hx = x.reshape(1,3,256,192) #batch1#onnx inferenceort_sess = ort.InferenceSession('/home/ubuntu/PaddleClas/deploy/model.onnx')outputs = ort_sess.run(None, {'x': x})res = outputs[0][0]print(res)label = []#postprocess thresholdthreshold=0.5glasses_threshold=0.3hold_threshold=0.6# gendergender = 'Female' if res[22] > threshold else 'Male'label.append(gender)# ageage = age_list[np.argmax(res[19:22])]label.append(age)# directiondirection = direct_list[np.argmax(res[23:])]label.append(direction)# glassesglasses = 'Glasses: 'if res[1] > glasses_threshold:glasses += 'True'else:glasses += 'False'label.append(glasses)# hathat = 'Hat: 'if res[0] > threshold:hat += 'True'else:hat += 'False'label.append(hat)# hold objhold_obj = 'HoldObjectsInFront: 'if res[18] > hold_threshold:hold_obj += 'True'else:hold_obj += 'False'label.append(hold_obj)# bagbag = bag_list[np.argmax(res[15:18])]bag_score = res[15 + np.argmax(res[15:18])]bag_label = bag if bag_score > threshold else 'No bag'label.append(bag_label)# upperupper_res = res[4:8]upper_label = 'Upper:'sleeve = 'LongSleeve' if res[3] > res[2] else 'ShortSleeve'upper_label += ' {}'.format(sleeve)for i, r in enumerate(upper_res):if r > threshold:upper_label += ' {}'.format(upper_list[i])label.append(upper_label)# lowerlower_res = res[8:14]lower_label = 'Lower: 'has_lower = Falsefor i, l in enumerate(lower_res):if l > threshold:lower_label += ' {}'.format(lower_list[i])has_lower = Trueif not has_lower:lower_label += ' {}'.format(lower_list[np.argmax(lower_res)])label.append(lower_label)# shoeshoe = 'Boots' if res[14] > threshold else 'No boots'label.append(shoe)threshold_list = [0.5] * len(res)threshold_list[1] = glasses_thresholdthreshold_list[18] = hold_thresholdpred_res = (np.array(res) > np.array(threshold_list)).astype(np.int8).tolist()batch_res = []batch_res.append({"attributes": label, "output": pred_res})print(batch_res)
模型图
/usr/bin/python3.8 /home/ubuntu/PaddleClas/onnx_det.py [2.3782253e-05 9.2464471e-01 6.0528517e-05 9.9903035e-01 5.3226948e-053.0008525e-02 9.0562546e-01 6.0856342e-05 1.2665987e-05 7.5966120e-051.5583634e-04 9.9993360e-01 1.0728836e-05 1.2640655e-03 3.1024218e-052.3931676e-01 1.1415660e-02 3.8976073e-03 2.2351742e-06 5.1259995e-069.9999028e-01 2.5928020e-06 2.6336133e-02 9.9652946e-01 4.2269528e-035.5581331e-05][{'attributes': ['Male', 'Age18-60', 'Front', 'Glasses: True', 'Hat: False', 'HoldObjectsInFront: False', 'No bag', 'Upper: LongSleeve UpperPlaid', 'Lower: Trousers', 'No boots'], 'output': [0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0]}]Process finished with exit code 0
测试结果和命令行推理结果一致
三、mnn推理
ubuntu@ubuntu:~/MNN-2.6.0/build$ ./MNNConvert -f ONNX --modelFile /home/ubuntu/PaddleClas/deploy/model.onnx --MNNModel /home/ubuntu/PaddleClas/deploy/model.mnn --bizCode MNNThe device support i8sdot:0, support fp16:0, support i8mm: 0Start to Convert Other Model Format To MNN Model...[12:43:01] /home/ubuntu/MNN-2.6.0/tools/converter/source/onnx/onnxConverter.cpp:98: ONNX Model ir version: 8[12:43:01] /home/ubuntu/MNN-2.6.0/tools/converter/source/onnx/onnxConverter.cpp:99: ONNX Model opset version: 9Start to Optimize the MNN Net...274 op name is empty or dup, set to Const274inputTensors : [ x, ]outputTensors: [ sigmoid_2.tmp_0, ]Converted Success!
cmakelists.txt
cmake_minimum_required(VERSION 3.16)project(untitled22)set(CMAKE_CXX_FLAGS "-std=c++11")set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")set(CMAKE_CXX_STANDARD 11)include_directories(${CMAKE_SOURCE_DIR})include_directories(${CMAKE_SOURCE_DIR}/include)include_directories(${CMAKE_SOURCE_DIR}/include/MNN)find_package(OpenCV REQUIRED)#message(STATUS ${OpenCV_INCLUDE_DIRS})#添加头文件include_directories(${OpenCV_INCLUDE_DIRS})#链接Opencv库add_library(libmnn SHARED IMPORTED)set_target_properties(libmnn PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/lib/libMNN.so)add_executable(untitled22 main.cpp)target_link_libraries(untitled22 ${OpenCV_LIBS} libmnn )
main.cpp
#define _CRT_SECURE_NO_WARNINGS#include <iostream>#include <opencv2/imgproc.hpp>#include <opencv2/highgui.hpp>#include<MNN/Interpreter.hpp>#include<MNN/ImageProcess.hpp>#include <fstream>#include "rapidjson/document.h"#include "rapidjson/writer.h"#include "rapidjson/stringbuffer.h"using namespace cv;using namespace std;int main() {std::string age_list[] = {"AgeLess18", "Age18-60", "AgeOver60"};std::string gender_list[] = {"Female", "Male"};std::string direct_list[] = {"Front", "Side", "Back"};std::string glasses_list[] = {"True", "False"};std::string hat_list[] = {"True", "False"};std::string HoldObjectsInFront[] = {"True", "False"};std::string bag_list[] = {"HandBag", "ShoulderBag", "Backpack"};std::string upper_list[] = {"UpperStride", "UpperLogo", "UpperPlaid", "UpperSplice"};std::string lower_list[] = {"LowerStripe", "LowerPattern", "LongCoat", "Trousers", "Shorts", "Skirt&Dress"};float threshold = 0.5;cv::Mat srcimg = cv::imread("/home/ubuntu/PaddleClas/deploy/images/Pedestrain_Attr.jpg");int inpWidth = 192;int inpHeight = 256;Mat dst;resize(srcimg, dst, Size(inpWidth, inpHeight), cv::INTER_LINEAR);auto mnnNet = std::shared_ptr<MNN::Interpreter>(MNN::Interpreter::createFromFile("/home/ubuntu/PaddleClas/deploy/model.mnn"));auto t1 = std::chrono::steady_clock::now();MNN::ScheduleConfig netConfig;netConfig.type = MNN_FORWARD_CPU;netConfig.numThread = 4;auto session = mnnNet->createSession(netConfig);auto input = mnnNet->getSessionInput(session, nullptr);mnnNet->resizeTensor(input, {1, 3, (int) inpWidth, (int) inpHeight});mnnNet->resizeSession(session);MNN::CV::ImageProcess::Config config;const float mean_vals[3] = {255 * 0.485, 255 * 0.456, 255 * 0.406};const float norm_255[3] = {1 / (255 * 0.229), 1 / (255 * 0.224), 1 / (255 * 0.225)};std::shared_ptr<MNN::CV::ImageProcess> pretreat(MNN::CV::ImageProcess::create(MNN::CV::BGR, MNN::CV::RGB, mean_vals, 3,norm_255, 3));pretreat->convert(dst.data, (int) inpWidth, (int) inpHeight, dst.step[0], input);MNN::Tensor inputHost(input, input->getDimensionType());input->copyToHostTensor(&inputHost);mnnNet->runSession(session);auto output = mnnNet->getSessionOutput(session, "sigmoid_2.tmp_0");MNN::Tensor outputHost(output, output->getDimensionType());output->copyToHostTensor(&outputHost);auto score_ptr = outputHost.host<float>();int shape_h = outputHost.height();int shape_c = outputHost.channel();int shape_w = outputHost.width();int shape_s = outputHost.size();printf("---c= %d w= %d h= %d s= %d ----\n", shape_c, shape_w, shape_h, shape_s);std::vector<float> vec_score;for (int i = 0; i < outputHost.elementSize(); ++i) {float score = score_ptr[i];vec_score.push_back(score);// printf("%.4f, ",score);}rapidjson::Document doc;doc.SetArray();rapidjson::Document item_doc;item_doc.SetObject();rapidjson::Value strValue;rapidjson::Document::AllocatorType &allocator = doc.GetAllocator();if (vec_score[22] > threshold) {strValue = (rapidjson::StringRef(gender_list[0].c_str()));} else {strValue = (rapidjson::StringRef(gender_list[1].c_str()));}item_doc.AddMember("gender", strValue, allocator);int maxIndex = std::max_element(vec_score.begin() + 19, vec_score.begin() + 22) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(age_list[maxIndex - 19].c_str()));item_doc.AddMember("age", strValue, allocator);maxIndex = std::max_element(vec_score.begin() + 23, vec_score.end()) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(direct_list[maxIndex - 23].c_str()));item_doc.AddMember("direction", strValue, allocator);if (vec_score[1] > threshold) {strValue = (rapidjson::StringRef(glasses_list[0].c_str()));} else {strValue = (rapidjson::StringRef(glasses_list[1].c_str()));}item_doc.AddMember("Glasses", strValue, allocator);if (vec_score[0] > threshold) {strValue = (rapidjson::StringRef(hat_list[0].c_str()));} else {strValue = (rapidjson::StringRef(hat_list[1].c_str()));}item_doc.AddMember("Hat", strValue, allocator);if (vec_score[18] > threshold) {strValue = (rapidjson::StringRef(HoldObjectsInFront[0].c_str()));} else {strValue = (rapidjson::StringRef(HoldObjectsInFront[1].c_str()));}item_doc.AddMember("HoldObjectsInFront", strValue, allocator);maxIndex = std::max_element(vec_score.begin() + 15, vec_score.begin() + 18) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(bag_list[maxIndex - 15].c_str()));maxIndex = std::max_element(vec_score.begin() + 15, vec_score.begin() + 18) - vec_score.begin();if (vec_score[maxIndex] > threshold) {strValue = (rapidjson::StringRef(bag_list[maxIndex-15].c_str()));} else {strValue = (rapidjson::StringRef("No bag"));}// 计算最大值索引item_doc.AddMember("bag", strValue, allocator);std::string temp_state = "";if (vec_score[3] > vec_score[2]) {temp_state = "LongSleeve";} else {temp_state = "ShortSleeve";}for (int i = 4; i < 8; i++) {if (vec_score[i] > threshold)temp_state = temp_state + " " + upper_list[i-4];}strValue = (rapidjson::StringRef(temp_state.c_str()));// 计算最大值索引item_doc.AddMember("Upper", strValue, allocator);std::string lower_state = "";bool has_lower = false;for (int i = 8; i < 14; i++) {if (vec_score[i] > threshold) {lower_state = lower_state + " " + lower_list[i-8];has_lower = true;}}if(!has_lower){maxIndex = std::max_element(vec_score.begin() + 8, vec_score.begin() + 14) - vec_score.begin();lower_state = lower_state + " " + lower_list[maxIndex-8];}strValue = (rapidjson::StringRef(lower_state.c_str()));item_doc.AddMember("Lower",strValue, allocator);if (vec_score[14] > threshold) {strValue = (rapidjson::StringRef("Boosts"));} else {strValue = (rapidjson::StringRef("No boots"));}item_doc.AddMember("boots", strValue, allocator);doc.PushBack(item_doc, allocator);rapidjson::StringBuffer buffer;rapidjson::Writer<rapidjson::StringBuffer> write_json(buffer);doc.Accept(write_json);std::string buf_json_str = buffer.GetString();allocator.Clear();std::cout << buf_json_str << std::endl;cv::imwrite("a.jpg", srcimg);waitKey(0);destroyAllWindows();}
测试结果
/home/ubuntu/CLionProjects/mnn_demo/cmake-build-debug/untitled22The device support i8sdot:0, support fp16:0, support i8mm: 0---c= 26 w= 1 h= 1 s= 104 ----[{"gender":"Male","age":"Age18-60","direction":"Front","Glasses":"True","Hat":"False","HoldObjectsInFront":"False","bag":"No bag","Upper":"LongSleeve UpperPlaid","Lower":" Trousers","boots":"No boots"}]Process finished with exit code 0
四、ncnn推理 使用第五步的模型
ubuntu@ubuntu:~/ncnn/build/install/bin$ python3 -m onnxsim /home/ubuntu/PaddleClas/deploy/model.onnx /home/ubuntu/PaddleClas/deploy/model_sim.onnxSimplifying...Finish! Here is the difference:┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓┃┃ Original Model ┃ Simplified Model ┃┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩│ Add│ 29 │ 29││ BatchNormalization │ 27 │ 0││ Clip│ 28 │ 28││ Concat │ 1 │ 1││ Constant │ 204 │ 69││ Conv│ 32 │ 32││ Div│ 28 │ 28││ GlobalAveragePool │ 3 │ 3││ HardSigmoid │ 2 │ 2││ MatMul │ 1 │ 1││ Mul│ 31 │ 31││ Relu│ 2 │ 2││ Reshape │ 1 │ 1││ Shape │ 1 │ 1││ Sigmoid │ 1 │ 1││ Slice │ 1 │ 1││ Model Size │ 6.6MiB │ 6.5MiB │└────────────────────┴────────────────┴──────────────────┘ubuntu@ubuntu:~/ncnn/build/install/bin$ ./onnx2ncnn /home/ubuntu/PaddleClas/deploy/model_sim.onnx /home/ubuntu/PaddleClas/deploy/model_sim.param /home/ubuntu/PaddleClas/deploy/model_sim.binShape not supported yet!Unknown data type 0
cmakelists.txt
cmake_minimum_required(VERSION 3.16)project(main)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ")set(CMAKE_CXX_STANDARD 11)include_directories(${CMAKE_SOURCE_DIR}/include)include_directories(${CMAKE_SOURCE_DIR}/include/ncnn)find_package(OpenCV REQUIRED)include_directories(${OpenCV_INCLUDE_DIRS})#导入ncnnadd_library(libncnn STATIC IMPORTED)set_target_properties(libncnn PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/lib/libncnn.a)add_executable(main main.cpp )target_link_libraries(main ${OpenCV_LIBS} libncnn)
mian.cpp
#include <iostream>#include <fstream>#include "common.h"#include "ncnn/net.h"#include <fstream>#include "rapidjson/document.h"#include "rapidjson/writer.h"#include "rapidjson/stringbuffer.h"void pretty_print(const ncnn::Mat& m){for (int q=0; q<m.c; q++){const float* ptr = m.channel(q);for (int z=0; z<m.d; z++){for (int y=0; y<m.h; y++){for (int x=0; x<m.w; x++){printf("%f ", ptr[x]);}ptr += m.w;printf("\n");break;}printf("\n");break;}printf("------------------------\n");}}int main() {std::string age_list[] = {"AgeLess18", "Age18-60", "AgeOver60"};std::string gender_list[] = {"Female", "Male"};std::string direct_list[] = {"Front", "Side", "Back"};std::string glasses_list[] = {"True", "False"};std::string hat_list[] = {"True", "False"};std::string HoldObjectsInFront[] = {"True", "False"};std::string bag_list[] = {"HandBag", "ShoulderBag", "Backpack"};std::string upper_list[] = {"UpperStride", "UpperLogo", "UpperPlaid", "UpperSplice"};std::string lower_list[] = {"LowerStripe", "LowerPattern", "LongCoat", "Trousers", "Shorts", "Skirt&Dress"};cv::Mat srcimg = cv::imread("/home/ubuntu/PaddleClas/deploy/images/Pedestrain_Attr.jpg");float threshold=0.5;int inpWidth = 192;int inpHeight = 256;int h = srcimg.rows;int w = srcimg.cols;cv::Mat dst;resize(srcimg, dst, cv::Size(inpWidth, inpHeight), cv::INTER_LINEAR);ncnn::Mat input = ncnn::Mat::from_pixels_resize(dst.data, ncnn::Mat::PIXEL_BGR2RGB, w, h, inpWidth, inpHeight);ncnn::Net attr;attr.load_param("/home/ubuntu/PaddleClas/deploy/new_model_sim.param");attr.load_model("/home/ubuntu/PaddleClas/deploy/new_model_sim.bin");ncnn::Extractor extractor = attr.create_extractor();const float meanValues[3] = {0.485 * 255, 0.456 * 255, 0.406 * 255};const float normValues[3] = {1.0 / 0.229 / 255.0, 1.0 / 0.224 / 255.0, 1.0 / 0.225 / 255.0};input.substract_mean_normalize(meanValues, normValues);//pretty_print(input);extractor.input("x", input);ncnn::Mat out;extractor.extract("sigmoid_2.tmp_0", out);std::vector<float> vec_score;vec_score.resize(out.w);for (int j=0; j<out.w; j++){vec_score[j] = out[j];//printf("%.4f, ",vec_score[j]);}rapidjson::Document doc;doc.SetArray();rapidjson::Document item_doc;item_doc.SetObject();rapidjson::Value strValue;rapidjson::Document::AllocatorType &allocator = doc.GetAllocator();if (vec_score[22] > threshold) {strValue = (rapidjson::StringRef(gender_list[0].c_str()));} else {strValue = (rapidjson::StringRef(gender_list[1].c_str()));}item_doc.AddMember("gender", strValue, allocator);int maxIndex = std::max_element(vec_score.begin() + 19, vec_score.begin() + 22) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(age_list[maxIndex - 19].c_str()));item_doc.AddMember("age", strValue, allocator);maxIndex = std::max_element(vec_score.begin() + 23, vec_score.end()) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(direct_list[maxIndex - 23].c_str()));item_doc.AddMember("direction", strValue, allocator);if (vec_score[1] > threshold) {strValue = (rapidjson::StringRef(glasses_list[0].c_str()));} else {strValue = (rapidjson::StringRef(glasses_list[1].c_str()));}item_doc.AddMember("Glasses", strValue, allocator);if (vec_score[0] > threshold) {strValue = (rapidjson::StringRef(hat_list[0].c_str()));} else {strValue = (rapidjson::StringRef(hat_list[1].c_str()));}item_doc.AddMember("Hat", strValue, allocator);if (vec_score[18] > threshold) {strValue = (rapidjson::StringRef(HoldObjectsInFront[0].c_str()));} else {strValue = (rapidjson::StringRef(HoldObjectsInFront[1].c_str()));}item_doc.AddMember("HoldObjectsInFront", strValue, allocator);maxIndex = std::max_element(vec_score.begin() + 15, vec_score.begin() + 18) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(bag_list[maxIndex - 15].c_str()));maxIndex = std::max_element(vec_score.begin() + 15, vec_score.begin() + 18) - vec_score.begin();if (vec_score[maxIndex] > threshold) {strValue = (rapidjson::StringRef(bag_list[maxIndex-15].c_str()));} else {strValue = (rapidjson::StringRef("No bag"));}// 计算最大值索引item_doc.AddMember("bag", strValue, allocator);std::string temp_state = "";if (vec_score[3] > vec_score[2]) {temp_state = "LongSleeve";} else {temp_state = "ShortSleeve";}for (int i = 4; i < 8; i++) {if (vec_score[i] > threshold)temp_state = temp_state + " " + upper_list[i-4];}strValue = (rapidjson::StringRef(temp_state.c_str()));// 计算最大值索引item_doc.AddMember("Upper", strValue, allocator);std::string lower_state = "";bool has_lower = false;for (int i = 8; i < 14; i++) {if (vec_score[i] > threshold) {lower_state = lower_state + " " + lower_list[i-8];has_lower = true;}}if(!has_lower){maxIndex = std::max_element(vec_score.begin() + 8, vec_score.begin() + 14) - vec_score.begin();lower_state = lower_state + " " + lower_list[maxIndex-8];}strValue = (rapidjson::StringRef(lower_state.c_str()));item_doc.AddMember("Lower",strValue, allocator);if (vec_score[14] > threshold) {strValue = (rapidjson::StringRef("Boosts"));} else {strValue = (rapidjson::StringRef("No boots"));}item_doc.AddMember("boots", strValue, allocator);doc.PushBack(item_doc, allocator);rapidjson::StringBuffer buffer;rapidjson::Writer<rapidjson::StringBuffer> write_json(buffer);doc.Accept(write_json);std::string buf_json_str = buffer.GetString();allocator.Clear();std::cout << buf_json_str << std::endl;return 0;}
感觉结果有问题,待查(数据对不上,模型也很奇怪,有空在查原因)
/home/ubuntu/CLionProjects/ncnn_ocr/cmake-build-debug/main[{"gender":"Female","age":"Age18-60","direction":"Back","Glasses":"False","Hat":"False","HoldObjectsInFront":"True","bag":"No bag","Upper":"ShortSleeve UpperPlaid UpperSplice","Lower":" LowerPattern Shorts","boots":"No boots"}]Process finished with exit code 0
五、RKNN RK3588
先修理一下paddleClas模型
/PaddlePaddle/Paddle2ONNX/blob/develop/tools/onnx/paddle_infer_shape.py/PaddlePaddle/Paddle2ONNX/blob/develop/tools/onnx/rename_onnx_model.pyubuntu@ubuntu:~/PaddleClas/deploy$ python3 paddle_infer_shape.py --model_dir models/person_attribute_infer --model_filename inference.pdmodel --params_filename inference.pdiparams --save_dir new_model --input_shape_dict="{'x':[1,3,256,192]}"Start to load paddle model...I0720 19:25:59.364598 127723 :237] New Executor is Running.ubuntu@ubuntu:~/PaddleClas/deploy$ paddle2onnx --model_dir new_models --model_filename inference.pdmodel --params_filename inference.pdiparams --save_file new_model.onnx --enable_dev_version Trueubuntu@ubuntu:~/PaddleClas/deploy$ paddle2onnx --model_dir new_model --model_filename inference.pdmodel --params_filename inference.pdiparams --save_file new_model.onnx --enable_dev_version True[Paddle2ONNX] Start to parse PaddlePaddle model...[Paddle2ONNX] Model file path: new_model/inference.pdmodel[Paddle2ONNX] Paramters file path: new_model/inference.pdiparams[Paddle2ONNX] Start to parsing Paddle model...[Paddle2ONNX] Use opset_version = 9 for ONNX export.[Paddle2ONNX] PaddlePaddle model is exported as ONNX format now.-07-20 19:30:09 [INFO]===============Make PaddlePaddle Better!================-07-20 19:30:09 [INFO]A little survey: /?code=r8hu2s
然后转rknnn模型
from rknn.api import RKNNONNX_MODEL = '/home/ubuntu/PaddleClas/deploy/new_model.onnx'RKNN_MODEL = '/home/ubuntu/PaddleClas/deploy/new_model.rknn'if __name__ == '__main__':# Create RKNN objectrknn = RKNN(verbose=True)# pre-process configprint('--> config model')rknn.config(mean_values=[[127.5, 127.5, 127.5]], std_values=[[127.5, 127.5, 127.5]],target_platform='rk3588',quantized_dtype='asymmetric_quantized-8', optimization_level=3)print('done')print('--> Loading model')ret = rknn.load_onnx(model=ONNX_MODEL)if ret != 0:print('Load model failed!')exit(ret)print('done')# Build modelprint('--> Building model')ret = rknn.build(do_quantization=True, dataset='datasets.txt') # ,pre_compile=Trueif ret != 0:print('Build /home/ubuntu/PaddleClas/deploy/model.onnx failed!')exit(ret)print('done')# Export rknn modelprint('--> Export RKNN model')ret = rknn.export_rknn(RKNN_MODEL)if ret != 0:print('Export failed!')exit(ret)print('done')rknn.release()
cmakelists.txt
cmake_minimum_required(VERSION 3.13)project(3588_demo)set(CMAKE_CXX_FLAGS "-std=c++11")set(CMAKE_CXX_STANDARD 11)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lstdc++ ")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lstdc++")include_directories(${CMAKE_SOURCE_DIR})include_directories(${CMAKE_SOURCE_DIR}/include)message(STATUS ${OpenCV_INCLUDE_DIRS})#添加头文件include_directories(${OpenCV_INCLUDE_DIRS})find_package(OpenCV REQUIRED)#链接Opencv库add_library(librknn_api SHARED IMPORTED)set_target_properties(librknn_api PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/lib/librknn_api.so)add_executable(3588_demo main.cpp)target_link_libraries(3588_demo ${OpenCV_LIBS} librknn_api)
main.cpp
#include <stdio.h>#include <stdint.h>#include <stdlib.h>#include "iostream"#include <queue>#include "rknn_api.h"#include "opencv2/core/core.hpp"#include "opencv2/imgproc/imgproc.hpp"#include "opencv2/highgui/highgui.hpp"#include <chrono>#include "rapidjson/document.h"#include "rapidjson/writer.h"#include "rapidjson/stringbuffer.h"using namespace std;using namespace cv;void printRKNNTensor(rknn_tensor_attr *attr) {printf("index=%d name=%s n_dims=%d dims=[%d %d %d %d] n_elems=%d size=%d ""fmt=%d type=%d qnt_type=%d fl=%d zp=%d scale=%f\n",attr->index, attr->name, attr->n_dims, attr->dims[3], attr->dims[2],attr->dims[1], attr->dims[0], attr->n_elems, attr->size, 0, attr->type,attr->qnt_type, attr->fl, attr->zp, attr->scale);}int main(int argc, char **argv) {std::string age_list[] = {"AgeLess18", "Age18-60", "AgeOver60"};std::string gender_list[] = {"Female", "Male"};std::string direct_list[] = {"Front", "Side", "Back"};std::string glasses_list[] = {"True", "False"};std::string hat_list[] = {"True", "False"};std::string HoldObjectsInFront[] = {"True", "False"};std::string bag_list[] = {"HandBag", "ShoulderBag", "Backpack"};std::string upper_list[] = {"UpperStride", "UpperLogo", "UpperPlaid", "UpperSplice"};std::string lower_list[] = {"LowerStripe", "LowerPattern", "LongCoat", "Trousers", "Shorts", "Skirt&Dress"};const char *img_path = "../Pedestrain_Attr.jpg";const char *model_path = "../new_model.rknn";const char *post_process_type = "fp";//fpconst int target_width = 256;const int target_height = 192;const char *image_process_mode = "letter_box";const float threshold = 0.25;cv::Mat bgr = cv::imread(img_path);cv::Mat img_resize;cv::resize(bgr,img_resize,cv::Size(target_width,target_height));// Load modelFILE *fp = fopen(model_path, "rb");if (fp == NULL) {printf("fopen %s fail!\n", model_path);return -1;}fseek(fp, 0, SEEK_END);int model_len = ftell(fp);void *model = malloc(model_len);fseek(fp, 0, SEEK_SET);if (model_len != fread(model, 1, model_len, fp)) {printf("fread %s fail!\n", model_path);free(model);return -1;}rknn_context ctx = 0;int ret = rknn_init(&ctx, model, model_len, 0,0);if (ret < 0) {printf("rknn_init fail! ret=%d\n", ret);return -1;}/* Query sdk version */rknn_sdk_version version;ret = rknn_query(ctx, RKNN_QUERY_SDK_VERSION, &version,sizeof(rknn_sdk_version));if (ret < 0) {printf("rknn_init error ret=%d\n", ret);return -1;}printf("sdk version: %s driver version: %s\n", version.api_version,version.drv_version);/* Get input,output attr */rknn_input_output_num io_num;ret = rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, &io_num, sizeof(io_num));if (ret < 0) {printf("rknn_init error ret=%d\n", ret);return -1;}printf("model input num: %d, output num: %d\n", io_num.n_input,io_num.n_output);rknn_tensor_attr input_attrs[io_num.n_input];memset(input_attrs, 0, sizeof(input_attrs));for (int i = 0; i < io_num.n_input; i++) {input_attrs[i].index = i;ret = rknn_query(ctx, RKNN_QUERY_INPUT_ATTR, &(input_attrs[i]),sizeof(rknn_tensor_attr));if (ret < 0) {printf("rknn_init error ret=%d\n", ret);return -1;}printRKNNTensor(&(input_attrs[i]));}rknn_tensor_attr output_attrs[io_num.n_output];memset(output_attrs, 0, sizeof(output_attrs));for (int i = 0; i < io_num.n_output; i++) {output_attrs[i].index = i;ret = rknn_query(ctx, RKNN_QUERY_OUTPUT_ATTR, &(output_attrs[i]),sizeof(rknn_tensor_attr));printRKNNTensor(&(output_attrs[i]));}int input_channel = 3;int input_width = 0;int input_height = 0;if (input_attrs[0].fmt == RKNN_TENSOR_NCHW) {printf("model is NCHW input fmt\n");input_width = input_attrs[0].dims[0];input_height = input_attrs[0].dims[1];printf("input_width=%d input_height=%d\n", input_width, input_height);} else {printf("model is NHWC input fmt\n");input_width = input_attrs[0].dims[1];input_height = input_attrs[0].dims[2];printf("input_width=%d input_height=%d\n", input_width, input_height);}printf("model input height=%d, width=%d, channel=%d\n", input_height, input_width,input_channel);/* Init input tensor */rknn_input inputs[1];memset(inputs, 0, sizeof(inputs));inputs[0].index = 0;inputs[0].buf = img_resize.data;inputs[0].type = RKNN_TENSOR_UINT8;inputs[0].size = input_width * input_height * input_channel;inputs[0].fmt = RKNN_TENSOR_NHWC;inputs[0].pass_through = 0;/* Init output tensor */rknn_output outputs[io_num.n_output];memset(outputs, 0, sizeof(outputs));for (int i = 0; i < io_num.n_output; i++) {if (strcmp(post_process_type, "fp") == 0) {outputs[i].want_float = 1;} else if (strcmp(post_process_type, "u8") == 0) {outputs[i].want_float = 0;}}printf("img.cols: %d, img.rows: %d\n", img_resize.cols, img_resize.rows);auto t1=std::chrono::steady_clock::now();rknn_inputs_set(ctx, io_num.n_input, inputs);ret = rknn_run(ctx, NULL);if (ret < 0) {printf("ctx error ret=%d\n", ret);return -1;}ret = rknn_outputs_get(ctx, io_num.n_output, outputs, NULL);if (ret < 0) {printf("outputs error ret=%d\n", ret);return -1;}/* Post process */std::vector<float> out_scales;std::vector<uint8_t> out_zps;for (int i = 0; i < io_num.n_output; ++i) {out_scales.push_back(output_attrs[i].scale);out_zps.push_back(output_attrs[i].zp);}std::vector<float> vec_score;for(int i=0;i<output_attrs[0].n_elems;i++){vec_score.push_back(((float*)outputs)[i]);}rapidjson::Document doc;doc.SetArray();rapidjson::Document item_doc;item_doc.SetObject();rapidjson::Value strValue;rapidjson::Document::AllocatorType &allocator = doc.GetAllocator();if (vec_score[22] > threshold) {strValue = (rapidjson::StringRef(gender_list[0].c_str()));} else {strValue = (rapidjson::StringRef(gender_list[1].c_str()));}item_doc.AddMember("gender", strValue, allocator);int maxIndex = std::max_element(vec_score.begin() + 19, vec_score.begin() + 22) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(age_list[maxIndex - 19].c_str()));item_doc.AddMember("age", strValue, allocator);maxIndex = std::max_element(vec_score.begin() + 23, vec_score.end()) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(direct_list[maxIndex - 23].c_str()));item_doc.AddMember("direction", strValue, allocator);if (vec_score[1] > threshold) {strValue = (rapidjson::StringRef(glasses_list[0].c_str()));} else {strValue = (rapidjson::StringRef(glasses_list[1].c_str()));}item_doc.AddMember("Glasses", strValue, allocator);if (vec_score[0] > threshold) {strValue = (rapidjson::StringRef(hat_list[0].c_str()));} else {strValue = (rapidjson::StringRef(hat_list[1].c_str()));}item_doc.AddMember("Hat", strValue, allocator);if (vec_score[18] > threshold) {strValue = (rapidjson::StringRef(HoldObjectsInFront[0].c_str()));} else {strValue = (rapidjson::StringRef(HoldObjectsInFront[1].c_str()));}item_doc.AddMember("HoldObjectsInFront", strValue, allocator);maxIndex = std::max_element(vec_score.begin() + 15, vec_score.begin() + 18) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(bag_list[maxIndex - 15].c_str()));maxIndex = std::max_element(vec_score.begin() + 15, vec_score.begin() + 18) - vec_score.begin();if (vec_score[maxIndex] > threshold) {strValue = (rapidjson::StringRef(bag_list[maxIndex-15].c_str()));} else {strValue = (rapidjson::StringRef("No bag"));}// 计算最大值索引item_doc.AddMember("bag", strValue, allocator);std::string temp_state = "";if (vec_score[3] > vec_score[2]) {temp_state = "LongSleeve";} else {temp_state = "ShortSleeve";}for (int i = 4; i < 8; i++) {if (vec_score[i] > threshold)temp_state = temp_state + " " + upper_list[i-4];}strValue = (rapidjson::StringRef(temp_state.c_str()));// 计算最大值索引item_doc.AddMember("Upper", strValue, allocator);std::string lower_state = "";bool has_lower = false;for (int i = 8; i < 14; i++) {if (vec_score[i] > threshold) {lower_state = lower_state + " " + lower_list[i-8];has_lower = true;}}if(!has_lower){maxIndex = std::max_element(vec_score.begin() + 8, vec_score.begin() + 14) - vec_score.begin();lower_state = lower_state + " " + lower_list[maxIndex-8];}strValue = (rapidjson::StringRef(lower_state.c_str()));item_doc.AddMember("Lower",strValue, allocator);if (vec_score[14] > threshold) {strValue = (rapidjson::StringRef("Boosts"));} else {strValue = (rapidjson::StringRef("No boots"));}item_doc.AddMember("boots", strValue, allocator);doc.PushBack(item_doc, allocator);rapidjson::StringBuffer buffer;rapidjson::Writer<rapidjson::StringBuffer> write_json(buffer);doc.Accept(write_json);std::string buf_json_str = buffer.GetString();allocator.Clear();std::cout << buf_json_str << std::endl;ret = rknn_outputs_release(ctx, io_num.n_output, outputs);if (ret < 0) {printf("rknn_query fail! ret=%d\n", ret);goto Error;}Error:if (ctx > 0)rknn_destroy(ctx);if (model)free(model);if (fp)fclose(fp);return 0;}
测试结果
/tmp/tmp.0UruCL55tW/cmake-build-debug/3588_demosdk version: 1.4.0 (a10f100eb@-09-09T09:07:14) driver version: 0.8.2model input num: 1, output num: 1index=0 name=x n_dims=4 dims=[3 192 256 1] n_elems=147456 size=147456 fmt=0 type=2 qnt_type=2 fl=0 zp=0 scale=0.007843index=0 name=sigmoid_2.tmp_0 n_dims=2 dims=[0 0 26 1] n_elems=26 size=26 fmt=0 type=2 qnt_type=2 fl=0 zp=-128 scale=0.003922model is NHWC input fmtinput_width=256 input_height=192model input height=192, width=256, channel=3img.cols: 256, img.rows: 192[{"gender":"Male","age":"AgeLess18","direction":"Front","Glasses":"False","Hat":"False","HoldObjectsInFront":"False","bag":"No bag","Upper":"ShortSleeve","Lower":" Trousers","boots":"No boots"}]Process finished with exit code 0
六、tensorRT推理
ubuntu@ubuntu:~/NVIDIA_CUDA-11.1_Samples/TensorRT-8.6.1.6/bin$ ./trtexec --onnx=/home/ubuntu/PaddleClas/deploy/model.onnx --saveEngine=/home/ubuntu/PaddleClas/deploy/model.engine --fp16
cmakelists.txt
cmake_minimum_required(VERSION 2.6)project(demo)add_definitions(-std=c++11)find_package(CUDA REQUIRED)include_directories(${CMAKE_SOURCE_DIR})# include and link dirs of cuda and tensorrt, you need adapt them if yours are different# cudainclude_directories(/usr/local/cuda/include)link_directories(/usr/local/cuda/lib64)# cudnnfind_package(OpenCV)include_directories(${OpenCV_INCLUDE_DIRS})add_executable(demo main.cpp)target_link_libraries(demo nvinfer cudart ${OpenCV_LIBS})
main.cpp (logging.h文件随便搜个,搞进去就行)
#include <fstream>#include <iostream>#include <vector>#include <opencv2/opencv.hpp>#include <dirent.h>#include "NvInfer.h"#include "cuda_runtime_api.h"#include "logging.h"#include "rapidjson/document.h"#include "rapidjson/writer.h"#include "rapidjson/stringbuffer.h"using namespace cv;using namespace std;#define CHECK(status) \do\{\auto ret = (status);\if (ret != 0)\{\cerr << "Cuda failure: " << ret << endl;\abort();\}\} while (0)#define DEVICE 0 // GPU idusing namespace nvinfer1;// stuff we know about the network and the input/output blobsconst char *INPUT_BLOB_NAME = "x";const char *OUTPUT_BLOB_NAME = "sigmoid_2.tmp_0";static Logger gLogger;void blobFromImage(Mat &img,float *blob) {cvtColor(img, img, COLOR_BGR2RGB);//printf("%d\n",img.total());int channels = 3;int img_h = img.rows;int img_w = img.cols;vector<float> mean = {0.485, 0.456, 0.406};vector<float> std = {0.229, 0.224, 0.225};for (size_t c = 0; c < channels; c++) {for (size_t h = 0; h < img_h; h++) {for (size_t w = 0; w < img_w; w++) {blob[c * img_w * img_h + h * img_w + w] =(((float) img.at<Vec3b>(h, w)[c]) / 255.0f - mean[c]) / std[c];}}}}void doInference(IExecutionContext &context, float *input, float *output, const int output_size, Size input_shape) {const ICudaEngine &engine = context.getEngine();// Pointers to input and output device buffers to pass to engine.// Engine requires exactly IEngine::getNbBindings() number of buffers.assert(engine.getNbBindings() == 2);void *buffers[2];// In order to bind the buffers, we need to know the names of the input and output tensors.// Note that indices are guaranteed to be less than IEngine::getNbBindings()const int inputIndex = engine.getBindingIndex(INPUT_BLOB_NAME);assert(engine.getBindingDataType(inputIndex) == nvinfer1::DataType::kFLOAT);const int outputIndex = engine.getBindingIndex(OUTPUT_BLOB_NAME);assert(engine.getBindingDataType(outputIndex) == nvinfer1::DataType::kFLOAT);int mBatchSize = engine.getMaxBatchSize();// Create GPU buffers on deviceCHECK(cudaMalloc(&buffers[inputIndex], 3 * input_shape.height * input_shape.width * sizeof(float)));CHECK(cudaMalloc(&buffers[outputIndex], output_size * sizeof(float)));// Create streamcudaStream_t stream;CHECK(cudaStreamCreate(&stream));// DMA input batch data to device, infer on the batch asynchronously, and DMA output back to hostCHECK(cudaMemcpyAsync(buffers[inputIndex], input, 3 * input_shape.height * input_shape.width * sizeof(float),cudaMemcpyHostToDevice, stream));context.enqueue(1, buffers, stream, nullptr);CHECK(cudaMemcpyAsync(output, buffers[outputIndex], output_size * sizeof(float), cudaMemcpyDeviceToHost, stream));cudaStreamSynchronize(stream);// Release stream and bufferscudaStreamDestroy(stream);CHECK(cudaFree(buffers[inputIndex]));CHECK(cudaFree(buffers[outputIndex]));}int main(int argc, char **argv) {cudaSetDevice(DEVICE);std::string age_list[] = {"AgeLess18", "Age18-60", "AgeOver60"};std::string gender_list[] = {"Female", "Male"};std::string direct_list[] = {"Front", "Side", "Back"};std::string glasses_list[] = {"True", "False"};std::string hat_list[] = {"True", "False"};std::string HoldObjectsInFront[] = {"True", "False"};std::string bag_list[] = {"HandBag", "ShoulderBag", "Backpack"};std::string upper_list[] = {"UpperStride", "UpperLogo", "UpperPlaid", "UpperSplice"};std::string lower_list[] = {"LowerStripe", "LowerPattern", "LongCoat", "Trousers", "Shorts", "Skirt&Dress"};float threshold = 0.5;// create a model using the API directly and serialize it to a streamchar *trtModelStream{nullptr};size_t size{0};const string engine_file_path = "/home/ubuntu/PaddleClas/deploy/model.engine";ifstream file(engine_file_path, ios::binary);if (file.good()) {file.seekg(0, file.end);size = file.tellg();file.seekg(0, file.beg);trtModelStream = new char[size];assert(trtModelStream);file.read(trtModelStream, size);file.close();}const string input_video_path{argv[3]};IRuntime *runtime = createInferRuntime(gLogger);assert(runtime != nullptr);ICudaEngine *engine = runtime->deserializeCudaEngine(trtModelStream, size);assert(engine != nullptr);IExecutionContext *context = engine->createExecutionContext();assert(context != nullptr);delete[] trtModelStream;auto out_dims = engine->getBindingDimensions(1);auto output_size = 1;for (int j = 0; j < out_dims.nbDims; j++) {output_size *= out_dims.d[j];}static float *prob = new float[output_size];const int img_w = 192;const int img_h = 256;cv::Mat img = cv::imread("/home/ubuntu/PaddleClas/deploy/images/Pedestrain_Attr.jpg");Mat pr_img ;cv::resize(img,pr_img,cv::Size(img_w,img_h));float blob[img_h*img_w*3]={0};blobFromImage(pr_img,blob);// run inferencedoInference(*context, blob, prob, output_size, pr_img.size());std::vector<float> vec_score;for(int i=0;i<output_size;i++){vec_score.push_back(prob[i]);}rapidjson::Document doc;doc.SetArray();rapidjson::Document item_doc;item_doc.SetObject();rapidjson::Value strValue;rapidjson::Document::AllocatorType &allocator = doc.GetAllocator();if (vec_score[22] > threshold) {strValue = (rapidjson::StringRef(gender_list[0].c_str()));} else {strValue = (rapidjson::StringRef(gender_list[1].c_str()));}item_doc.AddMember("gender", strValue, allocator);int maxIndex = std::max_element(vec_score.begin() + 19, vec_score.begin() + 22) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(age_list[maxIndex - 19].c_str()));item_doc.AddMember("age", strValue, allocator);maxIndex = std::max_element(vec_score.begin() + 23, vec_score.end()) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(direct_list[maxIndex - 23].c_str()));item_doc.AddMember("direction", strValue, allocator);if (vec_score[1] > threshold) {strValue = (rapidjson::StringRef(glasses_list[0].c_str()));} else {strValue = (rapidjson::StringRef(glasses_list[1].c_str()));}item_doc.AddMember("Glasses", strValue, allocator);if (vec_score[0] > threshold) {strValue = (rapidjson::StringRef(hat_list[0].c_str()));} else {strValue = (rapidjson::StringRef(hat_list[1].c_str()));}item_doc.AddMember("Hat", strValue, allocator);if (vec_score[18] > threshold) {strValue = (rapidjson::StringRef(HoldObjectsInFront[0].c_str()));} else {strValue = (rapidjson::StringRef(HoldObjectsInFront[1].c_str()));}item_doc.AddMember("HoldObjectsInFront", strValue, allocator);maxIndex = std::max_element(vec_score.begin() + 15, vec_score.begin() + 18) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(bag_list[maxIndex - 15].c_str()));maxIndex = std::max_element(vec_score.begin() + 15, vec_score.begin() + 18) - vec_score.begin();if (vec_score[maxIndex] > threshold) {strValue = (rapidjson::StringRef(bag_list[maxIndex-15].c_str()));} else {strValue = (rapidjson::StringRef("No bag"));}// 计算最大值索引item_doc.AddMember("bag", strValue, allocator);std::string temp_state = "";if (vec_score[3] > vec_score[2]) {temp_state = "LongSleeve";} else {temp_state = "ShortSleeve";}for (int i = 4; i < 8; i++) {if (vec_score[i] > threshold)temp_state = temp_state + " " + upper_list[i-4];}strValue = (rapidjson::StringRef(temp_state.c_str()));// 计算最大值索引item_doc.AddMember("Upper", strValue, allocator);std::string lower_state = "";bool has_lower = false;for (int i = 8; i < 14; i++) {if (vec_score[i] > threshold) {lower_state = lower_state + " " + lower_list[i-8];has_lower = true;}}if(!has_lower){maxIndex = std::max_element(vec_score.begin() + 8, vec_score.begin() + 14) - vec_score.begin();lower_state = lower_state + " " + lower_list[maxIndex-8];}strValue = (rapidjson::StringRef(lower_state.c_str()));item_doc.AddMember("Lower",strValue, allocator);if (vec_score[14] > threshold) {strValue = (rapidjson::StringRef("Boosts"));} else {strValue = (rapidjson::StringRef("No boots"));}item_doc.AddMember("boots", strValue, allocator);doc.PushBack(item_doc, allocator);rapidjson::StringBuffer buffer;rapidjson::Writer<rapidjson::StringBuffer> write_json(buffer);doc.Accept(write_json);std::string buf_json_str = buffer.GetString();allocator.Clear();std::cout << buf_json_str << std::endl;// destroy the enginecontext->destroy();engine->destroy();runtime->destroy();return 0;}
输出结果
/home/ubuntu/ByteTrack/deploy/TensorRT/cpp/cmake-build-debug/demo[W] [TRT] CUDA lazy loading is not enabled. Enabling it can significantly reduce device memory usage and speed up TensorRT initialization. See "Lazy Loading" section of CUDA documentation /cuda/cuda-c-programming-guide/index.html#lazy-loading[W] [TRT] The getMaxBatchSize() function should not be used with an engine built from a network created with NetworkDefinitionCreationFlag::kEXPLICIT_BATCH flag. This function will always return 1.[W] [TRT] The enqueue() method has been deprecated when used with engines built from a network created with NetworkDefinitionCreationFlag::kEXPLICIT_BATCH flag. Please use enqueueV2() instead.[W] [TRT] Also, the batchSize argument passed into this function has no effect on changing the input shapes. Please use setBindingDimensions() function to change input shapes instead.[07/20/-18:36:37] [07/20/-18:36:37] [07/20/-18:36:37] [07/20/-18:36:37] [{"gender":"Male","age":"Age18-60","direction":"Front","Glasses":"True","Hat":"False","HoldObjectsInFront":"False","bag":"No bag","Upper":"LongSleeve UpperPlaid","Lower":" Trousers","boots":"No boots"}]Process finished with exit code 0
七、openvino的推理
ubuntu@ubuntu:~/clion-.1.1/bin$ python3 /opt/intel/openvino_/deployment_tools/model_optimizer/mo.py --input_model /home/ubuntu/PaddleClas/deploy/new_model.onnx --output_dir /home/ubuntu/PaddleClas/deploy/new_model --input_shape [1,3,256,192] --data_type FP16 --scale_values [255,255,255] --mean_values [0,0,0]Model Optimizer arguments:Common parameters:- Path to the Input Model: /home/ubuntu/PaddleClas/deploy/new_model.onnx- Path for generated IR: /home/ubuntu/PaddleClas/deploy/new_model- IR output name: new_model- Log level: ERROR- Batch: Not specified, inherited from the model- Input layers: Not specified, inherited from the model- Output layers: Not specified, inherited from the model- Input shapes: [1,3,256,192]- Mean values: [0,0,0]- Scale values: [255,255,255]- Scale factor: Not specified- Precision of IR: FP16- Enable fusing: True- Enable grouped convolutions fusing: True- Move mean values to preprocess section: None- Reverse input channels: FalseONNX specific parameters:- Inference Engine found in: /opt/intel/openvino_/python/python3.8/openvinoInference Engine version: .4.1-3926-14e67d86634-releases//4Model Optimizer version: .4.1-3926-14e67d86634-releases//4/opt/intel/openvino_/deployment_tools/model_optimizer/extensions/front/onnx/parameter_ext.py:20: DeprecationWarning: `mapping.TENSOR_TYPE_TO_NP_TYPE` is now deprecated and will be removed in a future release.To silence this warning, please use `helper.tensor_dtype_to_np_dtype` instead.'data_type': TENSOR_TYPE_TO_NP_TYPE[t_type.elem_type][ SUCCESS ] Generated IR version 10 model.[ SUCCESS ] XML file: /home/ubuntu/PaddleClas/deploy/new_model/new_model.xml[ SUCCESS ] BIN file: /home/ubuntu/PaddleClas/deploy/new_model/new_model.bin[ SUCCESS ] Total execution time: 5.49 seconds. [ SUCCESS ] Memory consumed: 110 MB. It's been a while, check for a new version of Intel(R) Distribution of OpenVINO(TM) toolkit here /content/www/us/en/develop/tools/openvino-toolkit/download.html?cid=other&source=prod&campid=ww__bu_IOTG_OpenVINO--4-LTS&content=upg_all&medium=organic or on the GitHub*
使用clion
使用CLion进行阅读调试代码(Debug)#先进入clion.sh位置source /opt/intel/openvino_/bin/setupvars.sh先进入clion.sh位置 (/home/ubuntu/CLion-.3.2/clion-.3.2/bin) 然后sh clion.sh
cmakelists.txt
cmake_minimum_required(VERSION 3.4.1)set(CMAKE_CXX_STANDARD 14)project(untitled23)find_package(OpenCV REQUIRED)find_package(ngraph REQUIRED)find_package(InferenceEngine REQUIRED)include_directories(${OpenCV_INCLUDE_DIRS}${CMAKE_CURRENT_SOURCE_DIR}${CMAKE_CURRENT_BINARY_DIR})add_executable(untitled23 main.cpp)target_link_libraries(untitled23${InferenceEngine_LIBRARIES}${NGRAPH_LIBRARIES}${OpenCV_LIBS})
main.cpp
#include <opencv2/opencv.hpp>#include <inference_engine.hpp>#include <iostream>#include <chrono>#include <opencv2/dnn/dnn.hpp>#include <cmath>#include "rapidjson/document.h"#include "rapidjson/writer.h"#include "rapidjson/stringbuffer.h"using namespace std;using namespace cv;using namespace InferenceEngine;int main(int argc, char const *argv[]) {std::string age_list[] = {"AgeLess18", "Age18-60", "AgeOver60"};std::string gender_list[] = {"Female", "Male"};std::string direct_list[] = {"Front", "Side", "Back"};std::string glasses_list[] = {"True", "False"};std::string hat_list[] = {"True", "False"};std::string HoldObjectsInFront[] = {"True", "False"};std::string bag_list[] = {"HandBag", "ShoulderBag", "Backpack"};std::string upper_list[] = {"UpperStride", "UpperLogo", "UpperPlaid", "UpperSplice"};std::string lower_list[] = {"LowerStripe", "LowerPattern", "LongCoat", "Trousers", "Shorts", "Skirt&Dress"};float threshold = 0.5;string _xml_path = "/home/ubuntu/PaddleClas/deploy/new_model/new_model.xml";ExecutableNetwork _network;OutputsDataMap _outputinfo;//参数区Core ie;auto cnnNetwork = ie.ReadNetwork(_xml_path);//输入设置InputsDataMap inputInfo(cnnNetwork.getInputsInfo());InputInfo::Ptr& input = inputInfo.begin()->second;string _input_name = inputInfo.begin()->first;input->setPrecision(Precision::FP32);input->getInputData()->setLayout(Layout::NCHW);ICNNNetwork::InputShapes inputShapes = cnnNetwork.getInputShapes();SizeVector& inSizeVector = inputShapes.begin()->second;cnnNetwork.reshape(inputShapes);//输出设置_outputinfo = OutputsDataMap(cnnNetwork.getOutputsInfo());for (auto &output : _outputinfo) {output.second->setPrecision(Precision::FP32);}//获取可执行网络//_network = ie.LoadNetwork(cnnNetwork, "GPU");_network = ie.LoadNetwork(cnnNetwork, "CPU");Mat src = imread("/home/ubuntu/PaddleClas/deploy/images/Pedestrain_Attr.jpg");Mat inframe;int target_width=192;int target_height=256;resize(src, inframe, Size(target_width, target_height));if(inframe.empty()){cout << "无效图片输入" << endl;return false;}cvtColor(inframe,inframe,COLOR_BGR2RGB);size_t img_size = target_width*target_height;InferRequest::Ptr infer_request = _network.CreateInferRequestPtr();Blob::Ptr frameBlob = infer_request->GetBlob(_input_name);InferenceEngine::LockedMemory<void> blobMapped = InferenceEngine::as<InferenceEngine::MemoryBlob>(frameBlob)->wmap();float* blob_data = blobMapped.as<float*>();//nchwfor(size_t row =0;row<target_height;row++){for(size_t col=0;col<target_width;col++){for(size_t ch =0;ch<3;ch++){blob_data[img_size*ch + row*target_width + col] = float(inframe.at<Vec3b>(row,col)[ch]);}}}//执行预测infer_request->Infer();std::vector<float> vec_score;for (auto &output : _outputinfo) {InferenceEngine::SizeVector outputDims = output.second->getTensorDesc().getDims();std::cout <<"Input dimensions: "<<outputDims[0] <<" Output dimensions: "<<outputDims[1];auto output_f = output.first;std::cout<<output_f<<std::endl;Blob::Ptr blob = infer_request->GetBlob("sigmoid_2.tmp_0");LockedMemory<const void> blobMapped = as<MemoryBlob>(blob)->rmap();const float *output_blob = blobMapped.as<float *>();for(int i=0;i<outputDims[1];i++){vec_score.push_back(output_blob[i]);// std::cout<<" "<<output_blob[i]<<" ";}}rapidjson::Document doc;doc.SetArray();rapidjson::Document item_doc;item_doc.SetObject();rapidjson::Value strValue;rapidjson::Document::AllocatorType &allocator = doc.GetAllocator();if (vec_score[22] > threshold) {strValue = (rapidjson::StringRef(gender_list[0].c_str()));} else {strValue = (rapidjson::StringRef(gender_list[1].c_str()));}item_doc.AddMember("gender", strValue, allocator);int maxIndex = std::max_element(vec_score.begin() + 19, vec_score.begin() + 22) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(age_list[maxIndex - 19].c_str()));item_doc.AddMember("age", strValue, allocator);maxIndex = std::max_element(vec_score.begin() + 23, vec_score.end()) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(direct_list[maxIndex - 23].c_str()));item_doc.AddMember("direction", strValue, allocator);if (vec_score[1] > threshold) {strValue = (rapidjson::StringRef(glasses_list[0].c_str()));} else {strValue = (rapidjson::StringRef(glasses_list[1].c_str()));}item_doc.AddMember("Glasses", strValue, allocator);if (vec_score[0] > threshold) {strValue = (rapidjson::StringRef(hat_list[0].c_str()));} else {strValue = (rapidjson::StringRef(hat_list[1].c_str()));}item_doc.AddMember("Hat", strValue, allocator);if (vec_score[18] > threshold) {strValue = (rapidjson::StringRef(HoldObjectsInFront[0].c_str()));} else {strValue = (rapidjson::StringRef(HoldObjectsInFront[1].c_str()));}item_doc.AddMember("HoldObjectsInFront", strValue, allocator);maxIndex = std::max_element(vec_score.begin() + 15, vec_score.begin() + 18) - vec_score.begin();// 计算最大值索引strValue = (rapidjson::StringRef(bag_list[maxIndex - 15].c_str()));maxIndex = std::max_element(vec_score.begin() + 15, vec_score.begin() + 18) - vec_score.begin();if (vec_score[maxIndex] > threshold) {strValue = (rapidjson::StringRef(bag_list[maxIndex-15].c_str()));} else {strValue = (rapidjson::StringRef("No bag"));}// 计算最大值索引item_doc.AddMember("bag", strValue, allocator);std::string temp_state = "";if (vec_score[3] > vec_score[2]) {temp_state = "LongSleeve";} else {temp_state = "ShortSleeve";}for (int i = 4; i < 8; i++) {if (vec_score[i] > threshold)temp_state = temp_state + " " + upper_list[i-4];}strValue = (rapidjson::StringRef(temp_state.c_str()));// 计算最大值索引item_doc.AddMember("Upper", strValue, allocator);std::string lower_state = "";bool has_lower = false;for (int i = 8; i < 14; i++) {if (vec_score[i] > threshold) {lower_state = lower_state + " " + lower_list[i-8];has_lower = true;}}if(!has_lower){maxIndex = std::max_element(vec_score.begin() + 8, vec_score.begin() + 14) - vec_score.begin();lower_state = lower_state + " " + lower_list[maxIndex-8];}strValue = (rapidjson::StringRef(lower_state.c_str()));item_doc.AddMember("Lower",strValue, allocator);if (vec_score[14] > threshold) {strValue = (rapidjson::StringRef("Boosts"));} else {strValue = (rapidjson::StringRef("No boots"));}item_doc.AddMember("boots", strValue, allocator);doc.PushBack(item_doc, allocator);rapidjson::StringBuffer buffer;rapidjson::Writer<rapidjson::StringBuffer> write_json(buffer);doc.Accept(write_json);std::string buf_json_str = buffer.GetString();allocator.Clear();std::cout << buf_json_str << std::endl;return 0;}
测试结果
/home/ubuntu/CLionProjects/rknn/cmake-build-debug/untitled23Input dimensions: 1 Output dimensions: 26sigmoid_2.tmp_0[{"gender":"Male","age":"Age18-60","direction":"Front","Glasses":"True","Hat":"False","HoldObjectsInFront":"False","bag":"No bag","Upper":"LongSleeve UpperPlaid","Lower":" Trousers","boots":"No boots"}]Process finished with exit code 0
八、oak部署
转blob,套个人检测模型就行,已经证明可性