最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

手把手教你用c#制作一個(gè)小型桌面程序

 更新時(shí)間:2024年09月24日 09:39:37   作者:萊茶荼菜  
本文介紹了使用Visual?Studio創(chuàng)建DLL項(xiàng)目,并通過(guò)屬性管理器導(dǎo)入工程屬性表的方法,詳細(xì)闡述了制作Windows動(dòng)態(tài)庫(kù)的步驟,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

封裝dll

首先使用visual stdio 創(chuàng)建Dll新項(xiàng)目,然后屬性管理器導(dǎo)入自己的工程屬性表(如果沒(méi)有可以參考visual stdio 如何配置opencv等其他環(huán)境)

創(chuàng)建完成后 系統(tǒng)會(huì)自動(dòng)生成一些文件,其中 pch.cpp 先不要修改,pch.h中先導(dǎo)入自己需要用到的庫(kù),下面是我的代碼

pch.h

#pragma once
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <iostream>
#include <string>

現(xiàn)在編寫我們的接口代碼,我封裝的是resnet18的代碼:
首先添加源文件ResNetDll.cpp:

ResNetDll.cpp

#include "pch.h"
#include "ResNetDll.h"

// 全局變量,用于存儲(chǔ)模型路徑和圖像路徑
static std::string g_imagePath;
static std::string g_modelPath;

// 圖像預(yù)處理函數(shù)
cv::Mat transformImage(const std::string& imagePath) {
    cv::Mat image = cv::imread(imagePath);
    if (image.empty()) {
        throw std::runtime_error("Failed to load image.");
    }

    cv::Mat resizedImage;
    cv::resize(image, resizedImage, cv::Size(224, 224));

    cv::Mat floatImage;
    resizedImage.convertTo(floatImage, CV_32F, 1.0 / 255.0);

    cv::Mat normalizedImage;
    cv::Scalar mean(0.485, 0.456, 0.406);
    cv::Scalar stdDev(0.229, 0.224, 0.225);
    cv::subtract(floatImage, mean, normalizedImage);
    cv::divide(normalizedImage, stdDev, normalizedImage);

    // 從 BGR 轉(zhuǎn)換到 RGB
    cv::Mat rgbImage;
    cv::cvtColor(normalizedImage, rgbImage, cv::COLOR_BGR2RGB);

    return rgbImage;
}

// 推理函數(shù)
const char* run_inference() {
    static std::string result;

    try {
        // 加載 ONNX 模型
        cv::dnn::Net net = cv::dnn::readNetFromONNX(g_modelPath);
        if (net.empty()) {
            result = "Failed to load the model.";
            return result.c_str();
        }

        // 預(yù)處理圖像
        cv::Mat rgbImage = transformImage(g_imagePath);

        // 創(chuàng)建 blob 并設(shè)置為網(wǎng)絡(luò)輸入
        cv::Mat blob = cv::dnn::blobFromImage(rgbImage, 1.0, cv::Size(224, 224), cv::Scalar(), true, false);
        net.setInput(blob);

        // 執(zhí)行推理
        cv::Mat output = net.forward();

        // 處理輸出
        cv::Mat prob = output.reshape(1, 1);  // 變換成 1D 張量
        cv::Point classIdPoint;
        double confidence;
        // 用來(lái)找到矩陣或圖像中元素的最小值和最大值,以及它們所在的位置
        cv::minMaxLoc(prob, 0, &confidence, 0, &classIdPoint);
        int classId = classIdPoint.x;

        // 根據(jù)預(yù)測(cè)結(jié)果返回相應(yīng)的標(biāo)簽
        result = "Predicted Class ID: " + std::to_string(classId) + " with confidence: " + std::to_string(confidence);
        return result.c_str();
    }
    catch (const std::exception& e) {
        result = "Error occurred during inference: " + std::string(e.what());
        return result.c_str();
    }
}

// DLL 暴露的函數(shù),用于設(shè)置圖像路徑
extern "C" RESNETDLL_API void set_image_path(const char* imagePath) {
    g_imagePath = imagePath;
}

// DLL 暴露的函數(shù),用于設(shè)置模型路徑
extern "C" RESNETDLL_API void set_model_path(const char* modelPath) {
    g_modelPath = modelPath;
}

// DLL 暴露的函數(shù),運(yùn)行推理
extern "C" RESNETDLL_API const char* run_resnet() {
    return run_inference();
}

ResNetDll.h:

#pragma once

#ifdef RESNETDLL_EXPORTS
#define RESNETDLL_API __declspec(dllexport)
#else
#define RESNETDLL_API __declspec(dllimport)
#endif

extern "C" {
    // 設(shè)置圖像路徑
    RESNETDLL_API void set_image_path(const char* imagePath);

    // 設(shè)置模型路徑
    RESNETDLL_API void set_model_path(const char* modelPath);

    // 運(yùn)行推理
    RESNETDLL_API const char* run_resnet();
}

點(diǎn)擊生成dll,就封裝成了windows動(dòng)態(tài)庫(kù)

制作Demo

創(chuàng)建.NET Framework新項(xiàng)目,將之前生成的dll放在Demo文件夾的bin ->debug或是 release中(看你自己用的什么模式),
新建NativeMethods.cs 這個(gè)文件用于 導(dǎo)入 dll中的接口函數(shù)或類
我的代碼如下

NativeMethods.cs

using System;
using System.Runtime.InteropServices;

namespace ResNetApp
{
    public static class NativeMethods
    {
        // 導(dǎo)入 DLL 中的 set_image_path 函數(shù)
        [DllImport("ResNetDll.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void set_image_path(string imagePath);

        // 導(dǎo)入 DLL 中的 set_model_path 函數(shù)
        [DllImport("ResNetDll.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void set_model_path(string modelPath);

        // 導(dǎo)入 DLL 中的 run_resnet 函數(shù)
        [DllImport("ResNetDll.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr run_resnet();
    }
}

然后在窗口中拉入你想要的控件,這是我的窗口布局

布局完了之后會(huì)自動(dòng)生成Form1.Designer.cs 的窗口設(shè)計(jì)代碼,點(diǎn)擊控件按F4 還可以修改他們的屬性

Form1.cs

這個(gè)代碼 編寫你想要每個(gè)控件實(shí)現(xiàn)的功能:

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace ResNetApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void buttonSelectImage_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "圖像文件|*.bmp;*.jpg;*.jpeg;*.png";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                textBoxImagePath.Text = openFileDialog.FileName; // 顯示選擇的圖像路徑
            }
        }

        private void buttonSelectModel_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "ONNX 模型文件|*.onnx";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                textBoxModelPath.Text = openFileDialog.FileName; // 顯示選擇的模型路徑
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                string imagePath = textBoxImagePath.Text;
                string modelPath = textBoxModelPath.Text;

                if (string.IsNullOrEmpty(imagePath) || string.IsNullOrEmpty(modelPath))
                {
                    textBox1.Text = "請(qǐng)選擇圖像和模型路徑。";
                    return;
                }

                textBox1.Text = "開始運(yùn)行 ResNet ...";

                // 設(shè)置圖像路徑和模型路徑
                NativeMethods.set_image_path(imagePath);
                NativeMethods.set_model_path(modelPath);

                // 調(diào)用 DLL 執(zhí)行推理
                IntPtr resultPtr = NativeMethods.run_resnet();

                // 將返回的指針轉(zhuǎn)換為字符串
                string result = Marshal.PtrToStringAnsi(resultPtr);

                // 顯示結(jié)果
                textBox1.Text = result;
            }
            catch (Exception ex)
            {
                textBox1.Text = "錯(cuò)誤: " + ex.Message;
            }
        }

    }
}

Program.cs

我們還需要一個(gè)入口主程序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ResNetApp
{
    static class Program
    {
        /// <summary>
        /// 應(yīng)用程序的主入口點(diǎn)。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

完成之后點(diǎn)擊生成 就可以在bin中出現(xiàn)的你的.exe文件咯,是不是很簡(jiǎn)單呀~[狗頭]

總結(jié)

到此這篇關(guān)于用c#制作一個(gè)小型桌面程序的文章就介紹到這了,更多相關(guān)c#制作小型桌面程序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#繼承IList?接口的實(shí)現(xiàn)步驟

    C#繼承IList?接口的實(shí)現(xiàn)步驟

    C#中的IList<T>接口是.NET框架中的一種通用接口,它定義了一組在運(yùn)行時(shí)可以使用類型參數(shù)T的元素的集合,本文給大家介紹了C#繼承IList?接口的設(shè)計(jì)方法,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • C#中四步輕松使用log4net記錄本地日志的方法

    C#中四步輕松使用log4net記錄本地日志的方法

    下面小編就為大家分享一篇C#中四步輕松使用log4net記錄本地日志的方法,具有很好的參考價(jià)值。希望對(duì)大家有所幫助
    2017-11-11
  • C#實(shí)現(xiàn)Socket服務(wù)器及多客戶端連接的方式

    C#實(shí)現(xiàn)Socket服務(wù)器及多客戶端連接的方式

    這篇文章介紹了C#實(shí)現(xiàn)Socket服務(wù)器及多客戶端連接的方式,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-01-01
  • unity實(shí)現(xiàn)場(chǎng)景跳轉(zhuǎn)

    unity實(shí)現(xiàn)場(chǎng)景跳轉(zhuǎn)

    這篇文章主要為大家詳細(xì)介紹了unity實(shí)現(xiàn)場(chǎng)景跳轉(zhuǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • C# 變量作用域常用說(shuō)明小結(jié)

    C# 變量作用域常用說(shuō)明小結(jié)

    在C#編程中,變量作用域是一個(gè)重要概念,指的是變量在何處被定義和可以訪問(wèn)的范圍,正確理解和使用變量作用域有助于提升代碼的可讀性和避免潛在的錯(cuò)誤,感興趣的可以了解一下
    2024-10-10
  • C#實(shí)現(xiàn)按照指定長(zhǎng)度在數(shù)字前補(bǔ)0方法小結(jié)

    C#實(shí)現(xiàn)按照指定長(zhǎng)度在數(shù)字前補(bǔ)0方法小結(jié)

    這篇文章主要介紹了C#實(shí)現(xiàn)按照指定長(zhǎng)度在數(shù)字前補(bǔ)0方法,實(shí)例總結(jié)了兩個(gè)常用的數(shù)字補(bǔ)0的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • C#異步執(zhí)行任務(wù)的方法

    C#異步執(zhí)行任務(wù)的方法

    這篇文章主要介紹了C#異步執(zhí)行任務(wù)的方法,以一個(gè)簡(jiǎn)單實(shí)例形式分析了C#異步執(zhí)行的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • 深入c# GDI+簡(jiǎn)單繪圖的具體操作步驟(三)

    深入c# GDI+簡(jiǎn)單繪圖的具體操作步驟(三)

    前兩篇已經(jīng)基本向大家介紹了繪圖的基本知識(shí).那么,我就用我們上兩篇所學(xué)的,做幾個(gè)例子.我們先來(lái)做一個(gè)簡(jiǎn)單的--仿QQ截圖
    2013-05-05
  • C#使用分部類設(shè)計(jì)實(shí)現(xiàn)一個(gè)計(jì)算器

    C#使用分部類設(shè)計(jì)實(shí)現(xiàn)一個(gè)計(jì)算器

    分部類是C#4.5中的一個(gè)新特性,它的出現(xiàn)使得程序的結(jié)構(gòu)更加合理,代碼組織更加緊密,本文將使用分部類設(shè)計(jì)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的計(jì)算器,感興趣的小伙伴可以了解下
    2024-02-02
  • 使用C#將Excel轉(zhuǎn)為XML的兩種方案

    使用C#將Excel轉(zhuǎn)為XML的兩種方案

    在數(shù)據(jù)處理場(chǎng)景中,Excel文件常作為中間格式存在,但其結(jié)構(gòu)化程度有限,若需將Excel數(shù)據(jù)導(dǎo)入系統(tǒng)、進(jìn)行二次分析或與XML格式服務(wù)對(duì)接,Excel 轉(zhuǎn) XML 成為一項(xiàng)高頻需求,所以本文給大家介紹了使用C#將Excel轉(zhuǎn)為XML的兩種方案,需要的朋友可以參考下
    2025-09-09

最新評(píng)論

阿坝| 仁布县| 当涂县| 平果县| 景德镇市| 临海市| 哈巴河县| 峨眉山市| 康定县| 昌邑市| 玉屏| 青海省| 邹平县| 阿图什市| 栖霞市| 谢通门县| 仙居县| 乌拉特前旗| 塔河县| 沅江市| 比如县| 辽宁省| 聊城市| 钟山县| 古田县| 华容县| 榆林市| 当阳市| 乐山市| 聂拉木县| 邵阳县| 辽阳县| 五大连池市| 兰溪市| 龙陵县| 谢通门县| 黑水县| 清远市| 泸州市| 天津市| 民勤县|