当前位置: 首页 > article >正文

C# winform部署SAM2的onnx模型

【效果演示】【测试环境】vs2019net framework4.8.0opencvsharp4.13.0onnxruntime1.24.3【界面代码】using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using OpenCvSharp; using OpenCvSharp.Extensions; using System.IO; using System.Drawing.Imaging; namespace FIRC { public partial class Form1 : Form { private Mat originalImage; private bool isDragging; private System.Drawing.Point startPoint; private System.Drawing.Rectangle selectionRect; private Bitmap originalBitmap; private OpenCvSharp.Rect roi; private SamInferenceSession samSession; private Mat samMask; private bool isSamInitialized false; Mat displayImage new Mat(); public Form1() { InitializeComponent(); isDragging false; } private void btnLoadImage_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog new OpenFileDialog(); openFileDialog.Filter Image files (*.jpg, *.jpeg, *.png)|*.jpg;*.jpeg;*.png; if (openFileDialog.ShowDialog() DialogResult.OK) { string imagePath openFileDialog.FileName; originalImage Cv2.ImRead(imagePath); if (originalImage.Empty()) { lblStatus.Text 状态图片加载失败; return; } // 转换为Bitmap并显示 originalBitmap BitmapConverter.ToBitmap(originalImage); picOriginal.Image originalBitmap; picRectangle.Image null; picResult.Image null; lblStatus.Text 状态图片加载成功请在图片上绘制矩形; } } private void picOriginal_MouseDown(object sender, MouseEventArgs e) { if (originalImage null || originalBitmap null) return; isDragging true; startPoint e.Location; selectionRect new System.Drawing.Rectangle(startPoint, new System.Drawing.Size(0, 0)); UpdateSelection(); } private void picOriginal_MouseMove(object sender, MouseEventArgs e) { if (!isDragging || originalImage null || originalBitmap null) return; selectionRect new System.Drawing.Rectangle( Math.Min(startPoint.X, e.X), Math.Min(startPoint.Y, e.Y), Math.Abs(e.X - startPoint.X), Math.Abs(e.Y - startPoint.Y) ); UpdateSelection(); } private void picOriginal_MouseUp(object sender, MouseEventArgs e) { if (!isDragging || originalImage null || originalBitmap null) return; isDragging false; UpdateSelection(); // 确保矩形有一定大小 if (selectionRect.Width 10 selectionRect.Height 10) { // 计算实际图像上的矩形坐标 // 考虑图片在PictureBox中的实际显示位置和大小 RectangleF imageRect GetImageDisplayRect(); float scaleX (float)originalImage.Cols / imageRect.Width; float scaleY (float)originalImage.Rows / imageRect.Height; // 计算相对于图片显示区域的坐标 int x (int)((selectionRect.X - imageRect.X) * scaleX); int y (int)((selectionRect.Y - imageRect.Y) * scaleY); int width (int)(selectionRect.Width * scaleX); int height (int)(selectionRect.Height * scaleY); // 确保坐标在图像范围内 x Math.Max(0, x); y Math.Max(0, y); width Math.Min(width, originalImage.Cols - x); height Math.Min(height, originalImage.Rows - y); // 设置ROI roi new OpenCvSharp.Rect(x, y, width, height); // 显示矩形区域 // 截取矩形区域 Mat roiMat new Mat(originalImage, roi); Bitmap roiBitmap BitmapConverter.ToBitmap(roiMat); picRectangle.Image roiBitmap; // 运行SAM分割 RunSamSegmentation(); } } private RectangleF GetImageDisplayRect() { if (originalImage null || originalBitmap null) return RectangleF.Empty; // 计算图片在PictureBox中的实际显示位置和大小 float imageAspectRatio (float)originalImage.Width / originalImage.Height; float pictureBoxAspectRatio (float)picOriginal.Width / picOriginal.Height; float displayWidth, displayHeight, x, y; if (imageAspectRatio pictureBoxAspectRatio) { // 图片比PictureBox更宽按宽度缩放 displayWidth picOriginal.Width; displayHeight displayWidth / imageAspectRatio; x 0; y (picOriginal.Height - displayHeight) / 2; } else { // 图片比PictureBox更高按高度缩放 displayHeight picOriginal.Height; displayWidth displayHeight * imageAspectRatio; x (picOriginal.Width - displayWidth) / 2; y 0; } return new RectangleF(x, y, displayWidth, displayHeight); } private void UpdateSelection() { if (originalBitmap null) return; // 创建一个新的位图避免修改原始位图 Bitmap temp new Bitmap(picOriginal.Width, picOriginal.Height); using (Graphics g Graphics.FromImage(temp)) { // 绘制原始图像考虑缩放和居中 RectangleF imageRect GetImageDisplayRect(); g.DrawImage(originalBitmap, imageRect); // 绘制选择矩形 using (Pen pen new Pen(Color.Red, 2)) { g.DrawRectangle(pen, selectionRect); } } picOriginal.Image temp; } private void ShowRectangleArea() { if (originalImage null || roi.Width 0 || roi.Height 0) return; // 截取矩形区域 Mat roiMat new Mat(originalImage, roi); Bitmap roiBitmap BitmapConverter.ToBitmap(roiMat); picRectangle.Image roiBitmap; } private void RunSamSegmentation() { if (!isSamInitialized || originalImage null || samSession null) { lblStatus.Text 状态SAM模型未初始化或图像未加载; return; } try { lblStatus.Text 状态正在进行SAM分割...; Application.DoEvents(); // 获取SAM输入尺寸 OpenCvSharp.Size inputSize samSession.GetInputSize(); // 编码图像 var encoding samSession.Encode(originalImage); // 创建提示标记使用ROI var marks new ListSamInferenceSession.PromptMark { new SamInferenceSession.PromptMark { Type SamInferenceSession.MarkType.Rectangle, Data new float[] { roi.X, roi.Y, roi.X roi.Width, roi.Y roi.Height }, Label 2 } }; // 运行推理获取掩码 samMask samSession.PredictMasks(encoding, marks); double iou 1.0; // 将掩码调整回原始图像尺寸 Mat resizedMask new Mat(); Cv2.Resize(samMask, resizedMask, new OpenCvSharp.Size(originalImage.Cols, originalImage.Rows)); // 创建结果显示原图掩码叠加 //displayImage originalImage.Clone(); // 创建彩色掩码 Mat colorMask new Mat(originalImage.Size(), MatType.CV_8UC3, new Scalar(0, 0, 255)); Mat maskedColor new Mat(); colorMask.CopyTo(maskedColor, resizedMask); //// 叠加掩码到原图 //Cv2.AddWeighted(displayImage, 1.0, maskedColor, 0.5, 0, displayImage); //// 绘制ROI矩形 //Cv2.Rectangle(displayImage, roi, new Scalar(0, 255, 0), 2); // 显示结果 picResult.Image BitmapConverter.ToBitmap(maskedColor); lblStatus.Text string.Format(状态SAM分割完成 (IOU: {0:F3}), iou); } catch (Exception ex) { lblStatus.Text 状态SAM分割失败 ex.Message; MessageBox.Show(ex.ToString(), 分割错误, MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// summary /// 保存分割结果 /// /summary public void SaveSegmentationResult(string outputPath) { if (samMask null || samMask.Empty()) { throw new Exception(没有可保存的分割结果); } // 将掩码调整回原始图像尺寸 Mat resizedMask new Mat(); Cv2.Resize(samMask, resizedMask, new OpenCvSharp.Size(originalImage.Cols, originalImage.Rows)); // 保存掩码图像 Cv2.ImWrite(outputPath, resizedMask); } /// summary /// 获取分割后的对象带透明背景 /// /summary public Mat GetSegmentedObject() { if (samMask null || samMask.Empty() || originalImage null) { return null; } // 将掩码调整回原始图像尺寸 Mat resizedMask new Mat(); Cv2.Resize(samMask, resizedMask, new OpenCvSharp.Size(originalImage.Cols, originalImage.Rows)); // 创建RGBA输出图像 Mat result new Mat(originalImage.Size(), MatType.CV_8UC4); // 将原图转换为RGBA Mat originalRgba new Mat(); Cv2.CvtColor(originalImage, originalRgba, ColorConversionCodes.BGR2BGRA); // 应用掩码作为alpha通道 for (int i 0; i result.Rows; i) { for (int j 0; j result.Cols; j) { Vec4b pixel originalRgba.AtVec4b(i, j); byte maskValue resizedMask.Atbyte(i, j); result.AtVec4b(i, j) new Vec4b(pixel.Item0, pixel.Item1, pixel.Item2, maskValue); } } return result; } private void Form1_Load(object sender, EventArgs e) { try { // 加载模型 string encoderPath Path.Combine(AppDomain.CurrentDomain.BaseDirectory, models, sam2_hiera_tiny.encoder.onnx); string decoderPath Path.Combine(AppDomain.CurrentDomain.BaseDirectory, models, sam2_hiera_tiny.decoder.onnx); lblStatus.Text 状态正在初始化模型...; // 创建SAM推理会话 samSession new SamInferenceSession(encoderPath, decoderPath, 4); isSamInitialized true; lblStatus.Text 状态模型加载成功; } catch (Exception ex) { lblStatus.Text 状态模型加载失败 ex.Message; // 显示详细错误信息 MessageBox.Show(ex.ToString(), 错误, MessageBoxButtons.OK, MessageBoxIcon.Error); isSamInitialized false; } } } }【使用模型】sam2_hiera_tiny.decoder.onnxsam2_hiera_tiny.encoder.onnx【下载地址】【参考】gthub仓库X-anylabelIng标注工具里面sam2实现代码【注意事项】使用的sam2_hiera_tiny版本进行分割使用CPU推理速度比较快无需安装cudacudnn和带nvidia显卡

相关文章:

C# winform部署SAM2的onnx模型

【效果演示】【测试环境】vs2019net framework4.8.0opencvsharp4.13.0onnxruntime1.24.3【界面代码】using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using …...

Python 实战:基于朴素贝叶斯的中文评价情感分析(好评 / 差评自动识别)| 附完整可运行代码

前言 在电商、本地生活、内容平台等场景中,每天都会产生海量的用户评价文本。人工逐条区分好评 / 差评、挖掘用户痛点效率极低,而通过 NLP 机器学习技术实现评价情感倾向自动分类,可以帮助商家快速定位产品问题、优化服务体验,也…...

学习 JAVA DAY 01

今天是学习java的第一天,了解了java的发展历史,也知道现在处于互联网行业变革过程中。全球迎来第四次工业革命,人工智能(AI)将改变一切!Java定义的说法:Java是一门被企业广泛使用的高级计算机语…...

基于路径简化问题说明vector较于数组的优势

以前写程序时,遇到需要动态添加或删除元素的情况,我总是习惯用数组,然后维护一个计数器。但自从用了vector,我发现它的push_back和pop_back非常方便,特别是在做这道“简化路径”的题目的时候介绍vectorvector是C标准库…...

Leetcode128.『最长连续序列』学习笔记

1. 使用set的简洁解法 class Solution:def longestConsecutive(self, nums: List[int]) -> int:nums set(nums)longest 0for num in nums:if num - 1 not in nums:curr numwhile num in nums:num1longest max(longest, num - curr)return longest加了set之后&#xff0c…...

SpringBoot单元测试实战:Mock技术全解析

在 Spring Boot 中整合 Mock(模拟) 主要用于单元测试和集成测试,目的是隔离被测组件,避免依赖真实外部服务(如数据库、HTTP 接口、文件系统等)。Spring Boot 提供了强大的测试支持,结合 JUnit 5…...

239 滑动窗口最大值

题目 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1: 输入:nums [1,3,-1,-3,5,3,6,7], k 3…...

大模型连载8:词向量如何表示近义词?

余弦相似度和欧式距离 既然我们将 token 都转换到了高维的数学空间中,那么在高维数学空间中,如何来衡量两个 token (高维空间中为向量)的含义是相似的,还是相反的呢? 比如,在人类的认知中&…...

计算机毕业设计之springboot北工国际健身俱乐部

本系统为会员而设计制作北工国际健身俱乐部,旨在实现北工国际健身俱乐部智能化、现代化管理。本北工国际健身俱乐部管理自动化系统的开发和研制的最终目的是将北工国际健身俱乐部的运作模式从手工记录数据转变为网络信息查询管理,从而为现代管理人员的使…...

Day01笔记整理

java背景: java用于企业及应用开发,有JavaSE(基本)、JavaEE(企业)、JavaME(小型)三大技术平台。 jdk 1、jdk中的java语句运用: 在jdk安装目录的bin下,存在…...

计算机毕业设计之springboot基于宠物饲养管理APP的设计与实现

宠物饲养管理APP设计的目的是为用户提供宠物信息、年龄段、饮食信息、生活习惯等方面的平台。与PC端应用程序相比,宠物饲养管理APP的设计主要面向于宠物店,旨在为管理员和用户提供一个宠物饲养管理APP。用户可以通过APP及时查看宠物信息等。宠物饲养管理…...

AI原生应用领域意图识别的发展现状与未来展望

AI原生应用的"心灵翻译官":意图识别的进化之路与未来图景 关键词 意图识别、AI原生应用、自然语言理解、多模态交互、大模型微调、小样本学习、可解释性AI 摘要 在AI原生应用(AI-Native Apps)的世界里,意图识别就像…...

DVWA 搭建踩坑全记录:卡在 “Invalid database selected” 最后一关(新手求助!Help)

环境:Windows 10 phpStudy v8.1 MySQL 5.7.26 DVWA 最新版已做操作:1. phpStudy 安装成功,Apache 和 MySQL 都能启动 2. MySQL 命令行能连上(root 密码空) 3. DVWA 文件放在 WWW 下,config.inc.php 已创建并…...

华为OD机考双机位C卷 - 智能驾驶(Java Python JS GO C++ C)

智能驾驶 2026华为OD机试双机位C卷 - 华为OD上机考试双机位C卷 华为OD机试双机位C卷真题目录点击查看: 【全网首发】2026华为OD机位C卷 机考真题题库含考点说明以及在线OJ(OD上机考试双机位C卷) 题目描述 有一辆汽车需要从 m * n 的地图左上角(起点)开往地图的右下角(终…...

不懂代码,我用AI编程给5岁女儿开发了个流光画板(带你一步一步设计一个属于自己的流光画板)

我女儿经常玩的一个画板APP,但是经常弹广告。恰巧看到某家大模型说一句话生成一个画板,抠门的我想着AI编程不是说自己很厉害吗,我就用AI编程尝试去写一个。 靠着记忆让AI生成一个画板html,期初提示词比较笼统“帮我设计一个画板&a…...

数据即资产,安全即底线——企业资产数据安全控制管理的全维度实践与未来展望

在数字经济深度渗透的今天,数据已成为企业核心战略资产,是驱动业务创新、提升核心竞争力的关键引擎。从客户信息、财务数据到核心技术文档、商业秘密,数据的流转与应用贯穿企业运营全链条,但与此同时,数据泄露、篡改、…...

2026最新 springboot+vue邯郸特产交易平台

文章目录前言源码获取(稀缺资源,尽快转存到自己网盘,防止失效)详细视频演示技术栈后端技术前端技术功能模块后台管理端管理员功能商家功能具体实现截图后端框架SpringBoot前端框架Vue持久层框架MyBaits成功系统案例:代…...

想要实现真正的认知自动化?企业智脑定制难道不是必经之路?

想要实现真正的认知自动化?企业智脑定制难道不是必经之路?在企业数字化转型的漫长征途中,我们曾寄希望于ERP系统理顺流程,寄希望于RPA(机器人流程自动化)替代重复劳动。然而,当大模型浪潮席卷全…...

OSPF4种网络类型分析-Broadcast/NBMA/P2MP/P2P

一、四种OSPF网络类型分析1. Broadcast(广播模式) 网络特点:支持广播通信,所有设备共享同一广播域(如以太网、VLAN)。 邻居建立:路由协议通过多播Hello包自动发现邻居,并选举DR&…...

HandBrake - 开源免费视频格式转换/压缩转码压制工具

无论是下载高清电影,还是用手机录制的视频,很多时候文件体积都非常巨大。收藏保存或分享时会比较麻烦,因此常备一款真正好用的免费视频压缩压制/格式转换软件是很有必要的。 网上视频处理工具非常繁多,收费免费的一大堆&#xff…...

基于javaweb和mysql的ssm+maven情缘图书馆管理系统(java+ssm+tomcat+maven+mysql)

基于javaweb和mysql的ssmmaven情缘图书馆管理系统(javassmtomcatmavenmysql) 私信源码获取及调试交流 私信源码获取及调试交流 运行环境 Java≥8、MySQL≥5.7、Tomcat≥8 开发工具 eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计,大作业,…...

Winform Modbus 316线程 异步 λ表达式 泛型与数组 Encoding.ASCII.GetBytes bitConverter 大端小端 寄存器与label

this.Invoke 首先纠正:代码里不是List.Invoke,是**this.Invoke(this代表当前的FrmMain窗体对象),这是WinForm开发中跨线程更新UI的核心方法**,灯珠状态、仪表、图表这些UI控件的更新都靠它,下面…...

Hexo Butterfly 主题副标题不显示问题解决方案

问题描述 在 Hexo 根目录的 _config.yml 中配置了 subtitle,但网站没有显示副标题。 问题原因 配置位置错误! Butterfly 主题的副标题配置不在 Hexo 根目录的 _config.yml 中,而是在主题配置文件 themes/butterfly/_config.yml 中。 错误…...

深入解析MySQL数据库报错:`ERROR 1146 (42S02) Table ‘mysql.user‘ doesn‘t exist`

在安装或升级MySQL数据库时,你可能会遇到ERROR 1146 (42S02): Table mysql.user doesnt exist错误。这个错误表明尝试访问的mysql.user表不存在,这是MySQL用于存储用户账户和权限信息的关键系统表。本文将详细探讨这一错误的原因和解决方案,帮…...

带你轻松了解半导体CIM系统之AMHS (二)

👉带你轻松了解半导体CIM系统之AMHS (一) 话接上文,半导体AMHS系统是芯片制造晶圆厂中十分关键的系统,由搬运设备,存储与净化设备和控制系统组成。而在Fab(晶圆厂)中AMHS中的OHT也就是天车搬运十分繁忙&am…...

Android Studio 安装保姆级教程(mac版)

本文是一篇 从零开始的完整安装教程,适用于 Mac用户。 按照本文步骤操作,可以完成: 1:Android Studio 安装 2:Android SDK 配置 3:JDK 配置 4:Gradle 配置 5;Android 模拟器安装 6:第一个 Android 项目运行 一、下载 Android Studio 打…...

中小企业可用福尔蒂轻量化改性套件:含17种PA6/PBT配比+免费云端模拟

最近有位做汽车内饰件的朋友跟我聊起一个实际困扰:他们接了一个新项目,需要把传统PA6部件换成更轻、更耐热又不缩水的新材料,但试了几家供应商提供的改性料,不是注塑时流纹严重,就是批次间性能波动大,小批量…...

长亭 Xray Web 漏洞扫描器

长亭 Xray Web 漏洞扫描器 适用对象:安全研究人员、渗透测试工程师、开发人员、网络安全爱好者 前置知识:了解基本的 HTTP 协议、Web 安全概念(如 SQL 注入、XSS) 法律声明:本教程仅用于授权的安全测试、本地靶场练习…...

一次试样失败催生的技术革新:福尔蒂吹瓶专用ACR助剂逆向推演与流变拟合

那年夏天,一家饮料包装厂在调试新产线时遇到个棘手问题:吹瓶过程中频繁出现壁厚不均、肩部发白、甚至局部开裂——同一套模具、同一批PET切片、连温控参数都没动,就是反复试样失败。技术人员查了一周,最后把样本寄到了青岛福尔蒂新…...

国产替代:福尔蒂vs利安隆/金发/普立万在阻燃PC母粒的技术代差与应用边界

最近不少做工程塑料的朋友都在问一个问题:同样是阻燃PC母粒,为什么有些批次稳定性好、注塑不析出、火焰自熄快,而另一些却容易黄变、分散差、甚至过不了UL94 V-0测试?这个问题背后,其实不是简单的配方差异,…...