国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

TRT4-trt-integrate - 3 使用onnxruntime進行onnx的模型推理過程

這篇具有很好參考價值的文章主要介紹了TRT4-trt-integrate - 3 使用onnxruntime進行onnx的模型推理過程。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言:

  • onnx是microsoft開發(fā)的一個中間格式,而onnxruntime簡稱ort是microsoft為onnx開發(fā)的推理引擎。
  • 允許使用onnx作為輸入進行直接推理得到結果。

py接口的推理過程:

?main函數:


if __name__ == "__main__":

    session = onnxruntime.InferenceSession("workspace/yolov5s.onnx", providers=["CPUExecutionProvider"])#建立一個InferenceSession,塞進去的是onnx的路徑實際運算

    image = cv2.imread("workspace/car.jpg")
    image_input, M, IM = preprocess(image)
    pred = session.run(["output"], {"images": image_input})[0]
    boxes = post_process(pred, IM)

    for obj in boxes:
        left, top, right, bottom = map(int, obj[:4])
        confidence = obj[4]
        label = int(obj[6])
        cv2.rectangle(image, (left, top), (right, bottom), (0, 255, 0), 2)
        cv2.putText(image, f"{label}: {confidence:.2f}", (left, top+20), 0, 1, (0, 0, 255), 2, 16)

    cv2.imwrite("workspace/python-ort.jpg", image)
 session = onnxruntime.InferenceSession("workspace/yolov5s.onnx", providers=["CPUExecutionProvider"])

建立一個InferenceSession,塞進去的是onnx的路徑,實際運算的后端選用的是CPU

TRT4-trt-integrate - 3 使用onnxruntime進行onnx的模型推理過程,ort,c++

也可以選用cuda等等

    image = cv2.imread("workspace/car.jpg")
    image_input, M, IM = preprocess(image)

之后就是預處理

    pred = session.run(["output"], {"images": image_input})[0]
    boxes = post_process(pred, IM)

session.run就是運行的inference過程

TRT4-trt-integrate - 3 使用onnxruntime進行onnx的模型推理過程,ort,c++

?輸入第一個是output的name,決定了哪幾個節(jié)點作為輸出,就將這個名字傳遞給他

第二個是input的dict,這個意思就是如果有好多個輸入,那應該是將名字與輸入進行一一對應,比如"input1 ":input1? ,?? "input2":input2....

那么在這里output就是一個輸出的list,然后我們取第0項

TRT4-trt-integrate - 3 使用onnxruntime進行onnx的模型推理過程,ort,c++

就是這個樣子。

預處理:


def preprocess(image, input_w=640, input_h=640):
    scale = min(input_h / image.shape[0], input_w / image.shape[1])
    ox = (-scale * image.shape[1] + input_w + scale  - 1) * 0.5
    oy = (-scale * image.shape[0] + input_h + scale  - 1) * 0.5
    M = np.array([
        [scale, 0, ox],
        [0, scale, oy]
    ], dtype=np.float32)
    IM = cv2.invertAffineTransform(M)

    image_prep = cv2.warpAffine(image, M, (input_w, input_h), flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=(114, 114, 114))
    image_prep = (image_prep[..., ::-1] / 255.0).astype(np.float32)
    image_prep = image_prep.transpose(2, 0, 1)[None]
    return image_prep, M, IM

?文章來源地址http://www.zghlxwxcb.cn/news/detail-611686.html

后處理:

def nms(boxes, threshold=0.5):

    keep = []
    remove_flags = [False] * len(boxes)
    for i in range(len(boxes)):

        if remove_flags[i]:
            continue

        ib = boxes[i]
        keep.append(ib)
        for j in range(len(boxes)):
            if remove_flags[j]:
                continue

            jb = boxes[j]

            # class mismatch or image_id mismatch
            if ib[6] != jb[6] or ib[5] != jb[5]:
                continue

            cleft,  ctop    = max(ib[:2], jb[:2])
            #例子:
            #將 ib 的前兩個元素 [2, 3] 與 jb 的前兩個元素 [4, 1] 進行比較,并取其中較大的值。所以結果是 [4, 3]。
            cright, cbottom = min(ib[2:4], jb[2:4])
            cross = max(0, cright - cleft) * max(0, cbottom - ctop)
            union = max(0, ib[2] - ib[0]) * max(0, ib[3] - ib[1]) + max(0, jb[2] - jb[0]) * max(0, jb[3] - jb[1]) - cross
            iou = cross / union
            if iou >= threshold:
                remove_flags[j] = True
    return keep

def post_process(pred, IM, threshold=0.25):

    # b, n, 85
    boxes = []
    for image_id, box_id in zip(*np.where(pred[..., 4] >= threshold)):
        item = pred[image_id, box_id]
        cx, cy, w, h, objness = item[:5]
        label = item[5:].argmax()
        confidence = item[5 + label] * objness
        if confidence < threshold:
            continue

        boxes.append([cx - w * 0.5, cy - h * 0.5, cx + w * 0.5, cy + h * 0.5, confidence, image_id, label])

    boxes = np.array(boxes)
    lr = boxes[:, [0, 2]]
    tb = boxes[:, [1, 3]]
    boxes[:, [0, 2]] = lr * IM[0, 0] + IM[0, 2]
    boxes[:, [1, 3]] = tb * IM[1, 1] + IM[1, 2]

    # left, top, right, bottom, confidence, image_id, label
    boxes = sorted(boxes.tolist(), key=lambda x:x[4], reverse=True)
    return nms(boxes)

?我們可以發(fā)現(xiàn),真正的onnxruntime只有兩行,一個onnxruntime.InferenceSession,一個run就結束了。其余的都是和之前一樣的,這是非常好用便捷的,所以如果有模型需要作測試,是非常推薦用onnxruntime的

CPP接口推理過程:

Inference:

在main函數中只有一個inference


int main(){
    inference();
    return 0;
}

所以我們直接來到inference的解讀中

 auto engine_data = load_file("yolov5s.onnx");
//讀onnx文件
    Ort::Env env(ORT_LOGGING_LEVEL_INFO, "onnx");
//設置打印的日志級別    
    Ort::SessionOptions session_options;
//定義sessionoptions 類似于python中的    session =     onnxruntime.InferenceSession("workspace/yolov5s.onnx", providers=["CPUExecutionProvider"])

    auto mem = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
//設置MemoryInfo
    session_options.SetIntraOpNumThreads(1);
    session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED);
//啟動一些擴展
    Ort::Session session(env, "yolov5s.onnx", session_options);
    //創(chuàng)建session,將選項傳進去
    auto output_dims = session.GetOutputTypeInfo(0).GetTensorTypeAndShapeInfo().GetShape();
    //獲取output的shape
    const char *input_names[] = {"images"}, *output_names[] = {"output"};
    int input_batch = 1;
    int input_channel = 3;
    int input_height = 640;
    int input_width = 640;
    int64_t input_shape[] = {input_batch, input_channel, input_height, input_width};
    int input_numel = input_batch * input_channel * input_height * input_width;
    float* input_data_host = new float[input_numel];
    auto input_tensor = Ort::Value::CreateTensor(mem, input_data_host, input_numel, input_shape, 4);
    //創(chuàng)建一個Tensor,引用input_data_host中的數據

預處理:


    ///
    // letter box
    auto image = cv::imread("car.jpg");
    float scale_x = input_width / (float)image.cols;
    float scale_y = input_height / (float)image.rows;
    float scale = std::min(scale_x, scale_y);
    float i2d[6], d2i[6];
    i2d[0] = scale;  i2d[1] = 0;  i2d[2] = (-scale * image.cols + input_width + scale  - 1) * 0.5;
    i2d[3] = 0;  i2d[4] = scale;  i2d[5] = (-scale * image.rows + input_height + scale - 1) * 0.5;

    cv::Mat m2x3_i2d(2, 3, CV_32F, i2d);
    cv::Mat m2x3_d2i(2, 3, CV_32F, d2i);
    cv::invertAffineTransform(m2x3_i2d, m2x3_d2i);

    cv::Mat input_image(input_height, input_width, CV_8UC3);
    cv::warpAffine(image, input_image, m2x3_i2d, input_image.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar::all(114));
    cv::imwrite("input-image.jpg", input_image);

    int image_area = input_image.cols * input_image.rows;
    unsigned char* pimage = input_image.data;
    float* phost_b = input_data_host + image_area * 0;
    float* phost_g = input_data_host + image_area * 1;
    float* phost_r = input_data_host + image_area * 2;
    for(int i = 0; i < image_area; ++i, pimage += 3){
        // 注意這里的順序rgb調換了
        *phost_r++ = pimage[0] / 255.0f;
        *phost_g++ = pimage[1] / 255.0f;
        *phost_b++ = pimage[2] / 255.0f;
    }
    ///

制作輸出矩陣并運行:

    // 3x3輸入,對應3x3輸出
    int output_numbox = output_dims[1];
    int output_numprob = output_dims[2];
    int num_classes = output_numprob - 5;
    int output_numel = input_batch * output_numbox * output_numprob;
    float* output_data_host = new float[output_numel];
    int64_t output_shape[] = {input_batch, output_numbox, output_numprob};
    auto output_tensor = Ort::Value::CreateTensor(mem, output_data_host, output_numel, output_shape, 3);

    Ort::RunOptions options;
    session.Run(options, 
        (const char* const*)input_names, &input_tensor, 1, 
        (const char* const*)output_names, &output_tensor, 1
    );
//指定輸入輸出的name,tensor和個數,傳入tensor進行推理

后處理:

 // decode box
    vector<vector<float>> bboxes;
    float confidence_threshold = 0.25;
    float nms_threshold = 0.5;
    for(int i = 0; i < output_numbox; ++i){
        float* ptr = output_data_host + i * output_numprob;
        float objness = ptr[4];
        if(objness < confidence_threshold)
            continue;

        float* pclass = ptr + 5;
        int label     = std::max_element(pclass, pclass + num_classes) - pclass;
        float prob    = pclass[label];
        float confidence = prob * objness;
        if(confidence < confidence_threshold)
            continue;

        float cx     = ptr[0];
        float cy     = ptr[1];
        float width  = ptr[2];
        float height = ptr[3];
        float left   = cx - width * 0.5;
        float top    = cy - height * 0.5;
        float right  = cx + width * 0.5;
        float bottom = cy + height * 0.5;
        float image_base_left   = d2i[0] * left   + d2i[2];
        float image_base_right  = d2i[0] * right  + d2i[2];
        float image_base_top    = d2i[0] * top    + d2i[5];
        float image_base_bottom = d2i[0] * bottom + d2i[5];
        bboxes.push_back({image_base_left, image_base_top, image_base_right, image_base_bottom, (float)label, confidence});
    }
    printf("decoded bboxes.size = %d\n", bboxes.size());

    // nms
    std::sort(bboxes.begin(), bboxes.end(), [](vector<float>& a, vector<float>& b){return a[5] > b[5];});
    std::vector<bool> remove_flags(bboxes.size());
    std::vector<vector<float>> box_result;
    box_result.reserve(bboxes.size());

    auto iou = [](const vector<float>& a, const vector<float>& b){
        float cross_left   = std::max(a[0], b[0]);
        float cross_top    = std::max(a[1], b[1]);
        float cross_right  = std::min(a[2], b[2]);
        float cross_bottom = std::min(a[3], b[3]);

        float cross_area = std::max(0.0f, cross_right - cross_left) * std::max(0.0f, cross_bottom - cross_top);
        float union_area = std::max(0.0f, a[2] - a[0]) * std::max(0.0f, a[3] - a[1]) 
                         + std::max(0.0f, b[2] - b[0]) * std::max(0.0f, b[3] - b[1]) - cross_area;
        if(cross_area == 0 || union_area == 0) return 0.0f;
        return cross_area / union_area;
    };

    for(int i = 0; i < bboxes.size(); ++i){
        if(remove_flags[i]) continue;

        auto& ibox = bboxes[i];
        box_result.emplace_back(ibox);
        for(int j = i + 1; j < bboxes.size(); ++j){
            if(remove_flags[j]) continue;

            auto& jbox = bboxes[j];
            if(ibox[4] == jbox[4]){
                // class matched
                if(iou(ibox, jbox) >= nms_threshold)
                    remove_flags[j] = true;
            }
        }
    }
    printf("box_result.size = %d\n", box_result.size());

    for(int i = 0; i < box_result.size(); ++i){
        auto& ibox = box_result[i];
        float left = ibox[0];
        float top = ibox[1];
        float right = ibox[2];
        float bottom = ibox[3];
        int class_label = ibox[4];
        float confidence = ibox[5];
        cv::Scalar color;
        tie(color[0], color[1], color[2]) = random_color(class_label);
        cv::rectangle(image, cv::Point(left, top), cv::Point(right, bottom), color, 3);

        auto name      = cocolabels[class_label];
        auto caption   = cv::format("%s %.2f", name, confidence);
        int text_width = cv::getTextSize(caption, 0, 1, 2, nullptr).width + 10;
        cv::rectangle(image, cv::Point(left-3, top-33), cv::Point(left + text_width, top), color, -1);
        cv::putText(image, caption, cv::Point(left, top-5), 0, 1, cv::Scalar::all(0), 2, 16);
    }
    cv::imwrite("image-draw.jpg", image);

    delete[] input_data_host;
    delete[] output_data_host;
}

小結:

可以看到,這個與我們之前yolov5后處理沒什么太大的區(qū)別,關鍵只在于對于output_tensor和output作關聯(lián),input_tensor和input作關聯(lián)。

?

到了這里,關于TRT4-trt-integrate - 3 使用onnxruntime進行onnx的模型推理過程的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • Ubuntu環(huán)境下C++使用onnxruntime和Opencv進行YOLOv8模型部署

    Ubuntu環(huán)境下C++使用onnxruntime和Opencv進行YOLOv8模型部署

    目錄 環(huán)境配置 系統(tǒng)環(huán)境 項目文件路徑? 文件環(huán)境 ?config.txt ?CMakeLists.txt type.names ?讀取config.txt配置文件 修改圖片尺寸格式 讀取缺陷標志文件 生成缺陷隨機顏色標識 模型推理 推理結果獲取 缺陷信息還原并顯示 總代碼 Ubuntu18.04 onnxruntime-linux-x64 1.12.1:https://github.com/microsof

    2024年01月17日
    瀏覽(24)
  • vivado 使用IP Integrator源

    vivado 使用IP Integrator源

    使用IP Integrator源 在Vivado Design Suite中,您可以在RTL中添加和管理IP子系統(tǒng)塊設計(.bd)項目或設計。使用Vivado IP集成程序,您可以創(chuàng)建IP子系統(tǒng)塊設計。IP集成程序使您能夠通過實例化和將Vivado IP目錄中的多個IP核互連??梢越换?chuàng)建設計通過Vivado IDE中的IP integrator畫布或通過

    2024年01月18日
    瀏覽(19)
  • onnxruntime android版build & 使用

    onnx模型用在android平臺上時,需要build onnxruntime for android onnxruntime github 官方build for android文檔 參考項目中有build好的libonnxruntime.so, 但是你可能需要自己編譯,因為build的平臺環(huán)境是不一樣的。 你可以編譯成靜態(tài)庫libonnxruntime.a 或者 動態(tài)庫libonnxruntime.so 靜態(tài)庫可能有一個缺點就

    2024年02月05日
    瀏覽(12)
  • 使用onnxruntime-gpu 模型推理

    使用onnxruntime-gpu 模型推理

    1.安裝onnxruntime-gpu 新版的onnxruntime-gpu 即支持gpu的推理,也支持cpu的推理。 卸載舊的1.7.1 cpu版本,安裝新的gpu版本: 檢查是否安裝成功: 2.修改推理代碼 在推理代碼上增加 providers參數,選擇推理的框架??醋约褐С帜膫€就選擇自己支持的就可以了。 如果運行推理代碼出現(xiàn)

    2024年02月15日
    瀏覽(23)
  • 使用c++onnxruntime部署yolov5模型并使用CUDA加速(超詳細)

    使用c++onnxruntime部署yolov5模型并使用CUDA加速(超詳細)

    前言 1.Yolo簡介 2.onnxruntime簡介 3.Yolov5模型訓練及轉換 4.利用cmake向C++部署該onnx模型 總結 接到一個項目,需要用c++和單片機通信,還要使用yolo模型來做到目標檢測的任務,但目前網上的各種博客并沒有完整的流程教程,讓我在部署過程費了不少勁,也踩了不少坑(甚至一度把

    2024年02月02日
    瀏覽(19)
  • [segment-anything]使用onnxruntime部署sam模型,速度提高30倍!

    [segment-anything]使用onnxruntime部署sam模型,速度提高30倍!

    1、一臺帶有英偉達顯卡的電腦 2、anaconda環(huán)境 3、CUDA以及cudnn 最近sam火遍了cv圈,號稱可用一個模型分割一切,本文使用sam導出onnx模型,并通過onnxruntime(ort)進行部署,能夠明顯提升sam在本地的運算速度。話不多說,先看效果: pytorch運行時間: ort運行時間: 可見,sam的v

    2024年02月06日
    瀏覽(69)
  • pytorch 42 C#使用onnxruntime部署內置nms的yolov8模型

    pytorch 42 C#使用onnxruntime部署內置nms的yolov8模型

    在進行目標檢測部署時,通常需要自行編碼實現(xiàn)對模型預測結果的解碼及與預測結果的nms操作。所幸現(xiàn)在的各種部署框架對算子的支持更為靈活,可以在模型內實現(xiàn)預測結果的解碼,但仍然需要自行編碼實現(xiàn)對預測結果的nms操作。其實在onnx opset===11版本以后,其已支持將nms操

    2024年02月12日
    瀏覽(22)
  • 使用 API Gateway Integrator 在 Quarkus 中實施適用于 AWS Lambda 的 OpenAPI

    使用 API Gateway Integrator 在 Quarkus 中實施適用于 AWS Lambda 的 OpenAPI

    AWS API Gateway 集成使得使用符合 OpenAPI 標準的 Lambda Function 輕松實現(xiàn) REST API。 ????????它是一個 ? 允許以標準方式描述 REST API 的規(guī)范。 ? OpenAPI規(guī)范 (OAS) 為 REST API 定義了與編程語言無關的標準接口描述。這使得人類和計算機都可以發(fā)現(xiàn)和理解服務的功能,而無需訪問源代

    2024年02月13日
    瀏覽(40)
  • android 使用 onnxruntime 部署 hand_3d_landmark 手勢關鍵點檢測

    android 使用 onnxruntime 部署 hand_3d_landmark 手勢關鍵點檢測

    ?? 下面是使用 opencv-camera,實時處理區(qū)域內手勢關鍵點檢測 android 推理 demo。 首先是整合 opcv-camera 進去: 為了方便直接將整個 opencv-android-sdk 全部導入: ?然后在原來的項目模塊app中添加 opencv的 java 相關依賴,主要添加紅色兩行: app/build.grandle 最后在項目中要使用opencv的地

    2024年04月10日
    瀏覽(20)
  • SpringBoot中使用Spring integration加Eclipse Paho Java Client 實現(xiàn)MQTT客戶端

    Spring Integration 是一個開源的集成消息處理框架,它提供了消息傳遞、消息過濾、消息轉換、消息路由等功能,可以用于構建異步、分布式的系統(tǒng)。 Spring-integration-stream是Spring Integration框架的一個組件,用于在不同的系統(tǒng)和應用之間進行消息傳遞、集成和流處理。 它提供了一套

    2024年02月10日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包