c# 调用tensorrt c++ dll 推理yolov7 ,win10, cuda11.4.3 ,cudnn8.2,tensorrt8.2.1.8。

4 篇文章 0 订阅
2 篇文章 0 订阅

c# 调用tensorrt c++ dll 推理yolov7  ,win10, cuda11.4.3 ,cudnn8.2.4.15,tensorrt8.2.1.8。

1.首先需要生成自己的engine文件。

yolov7的 TensorRT c++推理,win10, cuda11.4.3 ,cudnn8.2,tensorrt8.2.1.8。_vokxchh的博客-CSDN博客yolov7的win10 cuda11.4.3 cudnn8.2 tensorrt8.2.1.8 c++推理https://blog.csdn.net/vokxchh/article/details/1287725302.然后生成c++ dll。代码如下。

yolov7tensorrt8生成c++dll,cuda11.4.3,cudnn8.2win10,vs2019-C++文档类资源-CSDN文库https://download.csdn.net/download/vokxchh/87402231

#include "config.h"
#include "model.h"
#include "cuda_utils.h"
#include "logging.h"
#include "utils.h"
#include "preprocess.h"
#include "postprocess.h"
#include <chrono>
#include <fstream>
#include "yolov7dll.h"

using namespace nvinfer1;

const static int kOutputSize = kMaxNumOutputBbox * sizeof(Detection) / sizeof(float) + 1;
static Logger gLogger;


void deserialize_engine(std::string& engine_name, IRuntime** runtime, ICudaEngine** engine, IExecutionContext** context) {
  std::ifstream file(engine_name, std::ios::binary);
  if (!file.good()) {
    std::cerr << "read " << engine_name << " error!" << std::endl;
    assert(false);
  }
  size_t size = 0;
  file.seekg(0, file.end);
  size = file.tellg();
  file.seekg(0, file.beg);
  char* serialized_engine = new char[size];
  assert(serialized_engine);
  file.read(serialized_engine, size);
  file.close();
  *runtime = createInferRuntime(gLogger);
  assert(*runtime);
  *engine = (*runtime)->deserializeCudaEngine(serialized_engine, size);
  assert(*engine);
  *context = (*engine)->createExecutionContext();
  assert(*context);
  delete[] serialized_engine;
}

void prepare_buffer(ICudaEngine* engine, float** input_buffer_device, float** output_buffer_device, float** output_buffer_host) {
  assert(engine->getNbBindings() == 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(kInputTensorName);
  const int outputIndex = engine->getBindingIndex(kOutputTensorName);
  assert(inputIndex == 0);
  assert(outputIndex == 1);
  // Create GPU buffers on device
  CUDA_CHECK(cudaMalloc((void**)input_buffer_device, kBatchSize * 3 * kInputH * kInputW * sizeof(float)));
  CUDA_CHECK(cudaMalloc((void**)output_buffer_device, kBatchSize * kOutputSize * sizeof(float)));

  *output_buffer_host = new float[kBatchSize * kOutputSize];
}

void infer(IExecutionContext& context, cudaStream_t& stream, void** buffers, float* output, int batchSize) {
  // infer on the batch asynchronously, and DMA output back to host
  context.enqueue(batchSize, buffers, stream, nullptr);
  CUDA_CHECK(cudaMemcpyAsync(output, buffers[1], batchSize * kOutputSize * sizeof(float), cudaMemcpyDeviceToHost, stream));
  CUDA_CHECK(cudaStreamSynchronize(stream));
}
IRuntime* runtime = nullptr;
ICudaEngine* engine = nullptr;
IExecutionContext* context = nullptr;
float* device_buffers[2];
float* output_buffer_host = nullptr;
cudaStream_t stream;
int Init(std::string engine_name)
{
    cudaSetDevice(kGpuId);

    // Deserialize the engine from file

    deserialize_engine(engine_name, &runtime, &engine, &context);
    
    CUDA_CHECK(cudaStreamCreate(&stream));

    cuda_preprocess_init(kMaxInputImageSize);

    // Prepare cpu and gpu buffers
   
    prepare_buffer(engine, &device_buffers[0], &device_buffers[1], &output_buffer_host);
    return 0;
}

void detect_yolov7_trt(cv::Mat img, std::string engine_name, Result* stu)
{
    std::vector<cv::Mat> img_batch;

    // cv::Mat img = cv::imread(img_dir2);
    img_batch.push_back(img);

    // Preprocess
    cuda_batch_preprocess(img_batch, device_buffers[0], kInputW, kInputH, stream);

    // Run inference

    infer(*context, stream, (void**)device_buffers, output_buffer_host, kBatchSize);

    // NMS
    std::vector<std::vector<Detection>> res_batch;
    batch_nms(res_batch, output_buffer_host, img_batch.size(), kOutputSize, kConfThresh, kNmsThresh);

    // Draw bounding boxes
    for (size_t i = 0; i < img_batch.size(); i++) {
        auto& res = res_batch[i];
        cv::Mat img = img_batch[i];
        for (size_t j = 0; j < res.size(); j++) {
            stu[j].classid = res[j].class_id;
            float l, r, t, b;
            float r_w = kInputW / (img.cols * 1.0);
            float r_h = kInputH / (img.rows * 1.0);
            if (r_h > r_w) {
                l = res[j].bbox[0] - res[j].bbox[2] / 2.f;
                r = res[j].bbox[0] + res[j].bbox[2] / 2.f;
                t = res[j].bbox[1] - res[j].bbox[3] / 2.f - (kInputH - r_w * img.rows) / 2;
                b = res[j].bbox[1] + res[j].bbox[3] / 2.f - (kInputH - r_w * img.rows) / 2;
                l = l / r_w;
                r = r / r_w;
                t = t / r_w;
                b = b / r_w;
            }
            else {
                l = res[j].bbox[0] - res[j].bbox[2] / 2.f - (kInputW - r_h * img.cols) / 2;
                r = res[j].bbox[0] + res[j].bbox[2] / 2.f - (kInputW - r_h * img.cols) / 2;
                t = res[j].bbox[1] - res[j].bbox[3] / 2.f;
                b = res[j].bbox[1] + res[j].bbox[3] / 2.f;
                l = l / r_h;
                r = r / r_h;
                t = t / r_h;
                b = b / r_h;
            }
            stu[j].l = l;
            stu[j].r = r;
            stu[j].t = t;
            stu[j].b = b;
        }
    }
   
}
const void yolov7_trt2(uchar* data, int width, int height, int stride, const char* eng_dir, Result* stu)
{
    std::string engine_name = eng_dir;
    if (engine == nullptr) Init(engine_name);
    cv::Mat img = cv::Mat(cv::Size(width, height), CV_8UC3, data, stride);
    detect_yolov7_trt(img, engine_name, stu);
}

const bool yolov7_trt(const char* img_dir, const char* eng_dir, Result* stu)
{
    std::string img_dir2 = img_dir;
    std::string engine_name = eng_dir;
    if (engine == nullptr) Init(engine_name);
    cv::Mat img = cv::imread(img_dir2);
    detect_yolov7_trt(img, engine_name, stu);
    return 0;
}




3.最后用c# 调用。代码如下。

c#调用yolov7tensorrtc++dll,推理-C#文档类资源-CSDN文库https://download.csdn.net/download/vokxchh/87402320

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.WebRequestMethods;

namespace WindowsFormsApp5
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        [DllImport("yolov7-trt.dll", CallingConvention = CallingConvention.Cdecl,CharSet = CharSet.Ansi)]
        extern static bool yolov7_trt(string imgdr,string engdr,[Out] Result[] re);//发送路径
        [DllImport("yolov7-trt.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        extern static bool yolov7_trt2(IntPtr data, int width, int height, int stride, string engdr, [Out] Result[] re);//发送图片

        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1), Serializable]
        public struct Result
        {
            public float result;//class_id
            public float l;
            public float r;
            public float t;
            public float b;
        }

        public static string engdr = Environment.CurrentDirectory + "\\yolov7-fp32.engine";
        public  Bitmap DrawRect(Bitmap bmp, Result[] re)
        {
           
            Graphics gg = Graphics.FromImage(bmp);
            Pen p = new Pen(Brushes.Red);
            foreach (var i in re)
            {  
                if (i.r == 0&& i.b == 0) { break; }
                gg.DrawRectangle(p, i.l, i.t, i.r - i.l, i.b - i.t);
                Font drawFont = new Font("Arial", 8, FontStyle.Bold, GraphicsUnit.Millimeter);
                SolidBrush drawBush = new SolidBrush(Color.Red);
                gg.DrawString(coco[(int)i.result], drawFont, drawBush, i.l, i.t);
            }
            gg.Dispose();
            return bmp;
        }
        Result[] yolov7_sendbmp(string path)//发送图片
        {
            Result[] re = new Result[30];
            Bitmap img = new Bitmap(path);
            BitmapData imgData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadWrite,
            PixelFormat.Format24bppRgb);
            int width = imgData.Width;
            int height = imgData.Height;
            int stride = imgData.Stride;
            try
            {
                yolov7_trt2(imgData.Scan0, width, height, stride, engdr, re);
            }
            catch (Exception ex)
            {
               MessageBox.Show(ex.ToString());
            }
            img.UnlockBits(imgData);
            DrawRect(img, re);

            pictureBox1.Image =img;
            return re;
         
        }

        private void button1_Click(object sender, EventArgs e)//发送图片的路径
        {
            Result[] re = new Result[30];
            label1.Text = "";
            Stopwatch stp = new Stopwatch();
            string imgdr = Environment.CurrentDirectory + "\\samples\\bus.bmp";
            stp.Start();
            yolov7_trt(imgdr,engdr,re);
            stp.Stop();
            Bitmap bp=(Bitmap)Image.FromFile(imgdr);
            DrawRect(bp, re);
            pictureBox1.Image = bp;
         
            label1.Text ="耗时:"+ stp.ElapsedMilliseconds.ToString() + "ms";
        }

        private void button2_Click(object sender, EventArgs e)//直接发送图片
        {
            label1.Text = "";
            Stopwatch stp = new Stopwatch();
            string imgdr = Environment.CurrentDirectory + "\\samples\\zidane.bmp";
            stp.Start();
            yolov7_sendbmp(imgdr);
            stp.Stop();
            label1.Text = "耗时:"+ stp.ElapsedMilliseconds.ToString() + "ms";
        }

        string[] coco;
        private void Form1_Load(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                coco = System.IO.File.ReadAllLines(Environment.CurrentDirectory + "\\coco.names");
                Result[] re = new Result[30];
                string imgdr = Environment.CurrentDirectory + "\\samples\\dog.bmp";

                yolov7_trt(imgdr, engdr, re);//先载入一次,预热。
                Bitmap bp = (Bitmap)Image.FromFile(imgdr);
                DrawRect(bp, re);
                pictureBox1.Image = bp;
                this.BeginInvoke(new MethodInvoker(delegate ()
                {
                    button1.Visible = true;
                    button2.Visible = true;
                    label1.Text = "载入完毕";
                }));

            });
        }
    }
}

可以 传入路径  或者  图片bitmap。实现推理。

以下增加置信率。请下载这个版本!

yolov7tensorrt8.2生成c++dll,并用c#调用,win10,cuda11.4.3,cudnn8.2-C#文档类资源-CSDN文库https://download.csdn.net/download/vokxchh/87406787增加置信率。

//

------------------------------------------------------------------------------------------------------------

以下用c++ 直接调用dll,推理,大致代码。 main.cpp

#include <iostream>
#include <windows.h>


struct Result
{
	float classid;
	float conf;
	float l;
	float r;
	float t;
	float b;
};
#pragma comment(lib, "yolov7-trt.lib")   
extern "C" __declspec(dllimport) const bool  yolov7_trt(const char* img_dir, const char* eng_dir, Result * stu);   



int main()
{
	char szFilePath[MAX_PATH + 1] = { 0 };
	GetModuleFileNameA(NULL, szFilePath, MAX_PATH);
	(strrchr(szFilePath, '\\'))[0] = 0;
	std::string path = szFilePath;
	std::string path1= path + "\\samples\\bus.bmp";
	std::string path2 = path + "\\yolov7-fp16.engine";
	const char* img_dir = path1.c_str();
	const char* eng_dir = path2.c_str();
	Result stu1[100];
	yolov7_trt(img_dir, eng_dir,stu1);
	for (size_t j = 0; j < 100; j++)
	{
		if (stu1[j].conf>0.5)	
			std::cerr << stu1[j].classid << " " << stu1[j].conf << " " << stu1[j].l << " " << stu1[j].r << " " << stu1[j].t << " " << stu1[j].b << std::endl;
	}
	system("pause");
}

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值