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

使用opencv-dnn+C++部署onnx肺區(qū)分割模型

這篇具有很好參考價值的文章主要介紹了使用opencv-dnn+C++部署onnx肺區(qū)分割模型。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1.環(huán)境:

windows + vscdoe + opencv3.4.15

2.流程:

①通過python將訓(xùn)練得到的模型轉(zhuǎn)化為onnx。

②通過C++調(diào)用onnx模型實現(xiàn)推理。

3.代碼:

① python代碼

ResUnet.py

import torch
from torch import nn
import torch.nn.functional as F


class DoubleConv(nn.Module):
    """(convolution => [BN] => ReLU) * 2"""

    def __init__(self, inChannels, outChannels, midChannels=None):
        super().__init__()
        if not midChannels:
            midChannels = outChannels
        self.doubleConv = nn.Sequential(
            nn.Conv2d(inChannels, midChannels, kernel_size=3, padding=1),
            nn.BatchNorm2d(midChannels),
            nn.ReLU(inplace=True),
            nn.Conv2d(midChannels, outChannels, kernel_size=3, padding=1),
            nn.BatchNorm2d(outChannels),
            nn.ReLU(inplace=True)
        )

    def forward(self, inNet):
        return self.doubleConv(inNet)


class ResBlock(nn.Module):
    def __init__(self, inChannels, outChannels):
        super(ResBlock, self).__init__()
        self.down1Sample = nn.Sequential(
            nn.Conv2d(inChannels, outChannels, kernel_size=1, stride=1, bias=False),
            nn.BatchNorm2d(outChannels))
        self.doubleConv = DoubleConv(inChannels, outChannels)
        self.down2Sample = nn.MaxPool2d(2)
        self.relu = nn.ReLU()

    def forward(self, inNet):
        identity = self.down1Sample(inNet)
        outNet = self.doubleConv(inNet)
        outNet = self.relu(outNet + identity)
        return self.down2Sample(outNet), outNet


class UpBlock(nn.Module):
    def __init__(self, inChannels, outChannels):
        super(UpBlock, self).__init__()
        self.upSample = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
        self.doubleConv = DoubleConv(inChannels, outChannels)

    def forward(self, downInput, skipInput):
        inNet = self.upSample(downInput)
        # input is CHW
        dify = skipInput.size()[2] - inNet.size()[2]
        difx = skipInput.size()[3] - inNet.size()[3]

        inNet = F.pad(inNet, [difx // 2, difx - difx // 2,
                              dify // 2, dify - dify // 2])
        inNet = torch.cat([inNet, skipInput], dim=1)
        return self.doubleConv(inNet)


class OutConv(nn.Module):
    def __init__(self, inChannels, outChannels):
        super(OutConv, self).__init__()
        self.conv = nn.Conv2d(inChannels, outChannels, kernel_size=1)

    def forward(self, inNet):
        return self.conv(inNet)


class ResUnet(nn.Module):
    """
    Hybrid solution of resnet blocks and double conv blocks
    """
    def __init__(self, inChannels=3, nClasses=1):
        super(ResUnet, self).__init__()

        self.downConv = nn.ModuleList()
        neuronNum = [64, 128, 256, 512, 1024]
        preChannels = inChannels
        for num in neuronNum[0:-1]:
            self.downConv.append(ResBlock(preChannels, num))
            preChannels = num
        self.doubleConv = DoubleConv(preChannels, neuronNum[-1])

        self.upConv = nn.ModuleList()
        for num1, num2 in zip(neuronNum[1::][::-1],  neuronNum[0:-1][::-1]):
            self.upConv.append(UpBlock(num1 + num2, num2))

        self.convFinal = OutConv(num2, nClasses)

    def forward(self, inNet):
        skipOuts = []
        for cnt, down in enumerate(self.downConv):
            inNet, skipOut = down(inNet)
            skipOuts.append(skipOut)
        inNet = self.doubleConv(inNet)

        for cnt, up in enumerate(self.upConv):
            inNet = up(inNet, skipOuts[-1 - cnt])

        outNet = self.convFinal(inNet)
        return outNet

export.py

def export(ckpt):
    model = ResUnet().to(DEVICE)
    stateDict = torch.load(ckpt)['state_dict']
    new_state_dict = OrderedDict()
    for key, val in stateDict.items():
        name = key[7:]  # remove "module."   
        new_state_dict[name] = val
       
    model.load_state_dict(new_state_dict)
    model.eval()

    inNet = torch.rand(1, 3, calSize[0], calSize[1]).to(DEVICE)
    torch.onnx.export(model, inNet, modelOnnx, opset_version=11, verbose=True, export_params=True, do_constant_folding=True)

② C++代碼:

#include <iostream>
#include <fstream>
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

using namespace std;
using namespace cv;
using namespace cv::dnn;
 

cv::Scalar meanDefault {0.485, 0.456, 0.406};
cv::Scalar stdDefault {0.229, 0.224, 0.225};
std::vector<std::string> extensions {"jpg", "bmp", "png", "jpeg"};
const int topk = 2;
static const string kWinName = "CT lung seg in OpenCV";

typedef struct
{
    int index;
    double value;
}sortArray;

cv::Mat Preprocess(cv::Mat pendImg)
{

    cv::Mat postImg;
    cv::resize(pendImg, postImg, cv::Size(512, 512));
    postImg.convertTo(postImg, CV_32F, 1.0/255.0);
    cv::subtract(postImg, meanDefault, postImg);
    cv::divide(postImg, stdDefault, postImg);
    return postImg;
}


bool cmp(sortArray a, sortArray b)
{
    return a.value>b.value;
}

std::vector<std::vector<cv::Point>> Postprocess(cv::Mat pendMask)
{

    
    cv::Mat bwImg;
    std::vector<std::vector<cv::Point>> contours; 
    std::vector<double> areas;

    cv::threshold(pendMask, bwImg, 1, 255.0, CV_THRESH_BINARY | CV_THRESH_OTSU);  
    cv::findContours(bwImg, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);  
    
    std::vector <sortArray> sortedArray(contours.size());
    for(int i=0;i<contours.size();++i){
        sortedArray[i].index = i;
        sortedArray[i].value = cv::contourArea(contours[i]);
    }
    std::sort(sortedArray.begin(), sortedArray.end(), cmp);
  
    std::vector<std::vector<cv::Point>> nContours;

    for (int i=0;i<sortedArray.size();i++)
    {

        if (i<topk) nContours.push_back(contours[sortedArray[i].index]);
        else break;

    }

    return nContours;
}

void GetImgFilenames(std::string path, std::vector<std::string>& imgFilenames)
{
    // imgFilenames.clear();
    if (path.find(".") != std::string::npos)
    {
        imgFilenames.push_back(path);
    }
    else
    {
        std::string fpath = path.append("*.*");
        std::vector<cv::String> allfiles;  //cv::String
        cv::glob(fpath, allfiles);
        for (int i = 0; i < allfiles.size(); i++)
        {
            size_t iPos = allfiles[i].rfind('.');
            std::string fileEx = allfiles[i].substr(iPos + 1, allfiles[i].length());
            // cout << fileEx << endl;
            if (std::find(extensions.begin(), extensions.end(), fileEx) != extensions.end())
            {
                imgFilenames.push_back(allfiles[i]);
            }
        }
    }
    // return;
}

cv::Mat Seg(std::string modelPath, std::string imgPath){

    // Net net = cv::dnn::readNetFromONNX(modelPath);
    cv::dnn::Net net = cv::dnn::readNet(modelPath);
    net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
    net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);

    cv::Mat Oimg = imread(imgPath);    
    cv::Mat img = Preprocess(Oimg.clone());
 
    cv::Mat blob = cv::dnn::blobFromImage(img, 1.0, Size(512, 512), cv::Scalar(0, 0, 0), true, false);    
    net.setInput(blob);    
 
    cv::Mat predOut = net.forward();  
    std::vector<cv::Mat> predTmp;
    cv::dnn::imagesFromBlob(predOut, predTmp); 

    cv::Mat predMask;
    predTmp[0] = (predTmp[0]>0);    
    predTmp[0].convertTo(predMask, CV_8UC1);
    return predMask;

}


int main()
{

    std::string modelBin = "weights/ctSeg.onnx";

    std::string path = "imgs/";
    std::vector<std::string> imgfiles;
  
    GetImgFilenames(path, imgfiles);

    for (int i=0; i<imgfiles.size(); i++)
    {
        // std::cout << imgfiles[i] << std::endl;
        cv::Mat predMask = Seg(modelBin, imgfiles[i]);
        cv::Mat Oimg = imread(imgfiles[i]);    
        cv::Mat imgShow = Oimg.clone();
        cv::resize(imgShow, imgShow, cv::Size(512, 512));

        std::vector<std::vector<cv::Point>> nContours = Postprocess(predMask);
        for (int i = 0; i < nContours.size(); i++)
        {
            cv::drawContours(imgShow, nContours, i, Scalar(0, 255, 0), 2, 8); 
        }
        cv::imshow("iShow", imgShow);
        cv::waitKey(0);
    }
    return 0;

}
4.結(jié)果:
c++調(diào)用onnx,圖像處理,opencv,深度學(xué)習(xí),計算機視覺,c++,Powered by 金山文檔
5.文件下載路徑:

鏈接:https://pan.baidu.com/s/1DDweuwcpSubLotU79c-jFw

提取碼:ZDWD

注:剛接觸深度學(xué)習(xí)完成的模型,所以采用了當時比較常見的網(wǎng)絡(luò),網(wǎng)絡(luò)模型偏大。文章來源地址http://www.zghlxwxcb.cn/news/detail-647895.html

到了這里,關(guān)于使用opencv-dnn+C++部署onnx肺區(qū)分割模型的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • OpenCV DNN模塊推理YOLOv5 ONNX模型方法

    本文檔主要描述 python 平臺,使用 opencv-python 深度神經(jīng)網(wǎng)絡(luò)模塊 dnn ,推理 YOLOv5 模型的方法。 文檔主要包含以下內(nèi)容: opencv-python 模塊的安裝 YOLOv5 模型格式的說明 ONNX 格式模型的加載 圖片數(shù)據(jù)的預(yù)處理 模型推理 推理結(jié)果后處理,包括 NMS , cxcywh 坐標轉(zhuǎn)換為 xyxy 坐標等 關(guān)鍵方

    2024年02月16日
    瀏覽(27)
  • YOLOv5 實例分割 用 OPenCV DNN C++ 部署

    YOLOv5 實例分割 用 OPenCV DNN C++ 部署

    如果之前從沒接觸過實例分割,建議先了解一下實例分割的輸出是什么。 實例分割兩個關(guān)鍵輸出是:mask系數(shù)、mask原型 本文參考自該項目(這么優(yōu)秀的代碼當然要給star!):GitHub - UNeedCryDear/yolov5-seg-opencv-onnxruntime-cpp: yolov5 segmentation with onnxruntime and opencv 目錄 Pre: 一、代碼總結(jié)

    2024年02月12日
    瀏覽(26)
  • [C++]使用純opencv去部署yolov9的onnx模型

    [C++]使用純opencv去部署yolov9的onnx模型

    【介紹】 部署 YOLOv9 ONNX 模型在 OpenCV 的 C++ 環(huán)境中涉及一系列步驟。以下是一個簡化的部署方案概述,以及相關(guān)的文案。 部署方案概述: 模型準備 :首先,你需要確保你有 YOLOv9 的 ONNX 模型文件。這個文件包含了模型的結(jié)構(gòu)和權(quán)重。 環(huán)境配置 :安裝 OpenCV 庫,并確保它支持

    2024年03月13日
    瀏覽(58)
  • yolov8 opencv dnn部署自己的模型

    yolov8 opencv dnn部署自己的模型

    源碼地址 本人使用的opencv c++ github代碼,代碼作者非本人 使用github源碼結(jié)合自己導(dǎo)出的onnx模型推理自己的視頻 推理條件 windows 10 Visual Studio 2019 Nvidia GeForce GTX 1070 opencv4.7.0 (opencv4.5.5在別的地方看到不支持yolov8的推理,所以只使用opencv4.7.0) 導(dǎo)出yolov8模型 yolov8版本: version = ‘8.

    2024年01月24日
    瀏覽(55)
  • yolov5 opencv dnn部署自己的模型

    yolov5 opencv dnn部署自己的模型

    github開源代碼地址 yolov5官網(wǎng)還提供的dnn、tensorrt推理鏈接 本人使用的opencv c++ github代碼,代碼作者非本人,也是上面作者推薦的鏈接之一 如果想要嘗試直接運行源碼中的yolo.cpp文件和yolov5s.pt推理sample.mp4,請參考這個鏈接的介紹 使用github源碼結(jié)合自己導(dǎo)出的onnx模型推理自己的

    2024年01月23日
    瀏覽(48)
  • 【模型部署 01】C++實現(xiàn)分類模型(以GoogLeNet為例)在OpenCV DNN、ONNXRuntime、TensorRT、OpenVINO上的推理部署

    【模型部署 01】C++實現(xiàn)分類模型(以GoogLeNet為例)在OpenCV DNN、ONNXRuntime、TensorRT、OpenVINO上的推理部署

    深度學(xué)習(xí)領(lǐng)域常用的基于CPU/GPU的推理方式有OpenCV DNN、ONNXRuntime、TensorRT以及OpenVINO。這幾種方式的推理過程可以統(tǒng)一用下圖來概述。整體可分為模型初始化部分和推理部分,后者包括步驟2-5。 以GoogLeNet模型為例,測得幾種推理方式在推理部分的耗時如下: 結(jié)論: GPU加速首選

    2024年02月06日
    瀏覽(26)
  • 【模型部署 01】C++實現(xiàn)GoogLeNet在OpenCV DNN、ONNXRuntime、TensorRT、OpenVINO上的推理部署

    【模型部署 01】C++實現(xiàn)GoogLeNet在OpenCV DNN、ONNXRuntime、TensorRT、OpenVINO上的推理部署

    深度學(xué)習(xí)領(lǐng)域常用的基于CPU/GPU的推理方式有OpenCV DNN、ONNXRuntime、TensorRT以及OpenVINO。這幾種方式的推理過程可以統(tǒng)一用下圖來概述。整體可分為模型初始化部分和推理部分,后者包括步驟2-5。 以GoogLeNet模型為例,測得幾種推理方式在推理部分的耗時如下: 結(jié)論: GPU加速首選

    2024年02月06日
    瀏覽(27)
  • YOLOV5(二):將pt轉(zhuǎn)為onnx模型并用opencv部署

    YOLOV5(二):將pt轉(zhuǎn)為onnx模型并用opencv部署

    yolov5s 6.0自帶export.py程序可將.pt轉(zhuǎn)為.onnx等,只需配置需要的環(huán)境即可。 1. 安裝環(huán)境 報錯:NVIDIA-tensorrt安裝失敗! 解決:從源碼安裝TensorRt: ①安裝CUDNN和CudaToolKit等GPU配置 ②從官網(wǎng)下載需要的rt版本:https://developer.nvidia.com/nvidia-tensorrt-8x-download ③解壓后,將lib文件夾添加到

    2024年02月10日
    瀏覽(22)
  • Opencv C++實現(xiàn)yolov5部署onnx模型完成目標檢測

    頭文件 命名空間 結(jié)構(gòu)體 Net_config 里面存了三個閾值和模型地址,其中 置信度 ,顧名思義,看檢測出來的物體的精準度。以測量值為中心,在一定范圍內(nèi),真值出現(xiàn)在該范圍內(nèi)的幾率。 endsWith()函數(shù) 判斷sub是不是s的子串 anchors_640圖像接收數(shù)組 根據(jù)圖像大小,選擇相應(yīng)長度的

    2024年02月13日
    瀏覽(25)
  • OpenCV DNN C++ 使用 YOLO 模型推理

    YOLO(You Only Look Once)是一種流行的目標檢測算法,因其速度快和準確度高而被廣泛應(yīng)用。OpenCV 的 DNN(Deep Neural Networks)模塊為我們提供了一個簡單易用的 API,用于加載和運行預(yù)先訓(xùn)練的深度學(xué)習(xí)模型。本文將詳細介紹如何使用 OpenCV 的 DNN 模塊來進行 YOLOv5 的目標檢測。 確保

    2024年02月08日
    瀏覽(17)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包