2.5 C#视觉程序开发实例2----图片内存管理 Csharp实现

news2024/11/19 13:19:23

2.5 C#视觉程序开发实例2----图片内存管理 Csharp实现

1 目标效果视频

mat-buffer

2 VisionManager类,专门用来管理Opencv相关的内存和 工具参数

2.1 定义一个mat_buffers数组
// Mat buffer 用于保存Mat 图片内存
//Mat[0]:register
//Mat[1]:cur img
//Mat[2-6]:colorfilter
//Mat[7-16]:grayfilter
public static int n_max_buffers = 17;
public Mat[,] mat_buffers;//Mat[camCount,17]
2.2 初始化Mat_buffer数组

VisionManager初始化时自动初始化内存数组

 public VisionManager()
{
   try
   { // 初始化 mat_buffers
       mat_buffers = new Mat[n_max_CamCount, n_max_buffers];
       for (int i = 0; i < n_max_CamCount; i++)
       {
           for (int j = 0; j < n_max_buffers; j++)
           {
               mat_buffers[i, j] = new Mat();
           }
       }
      
   }
   catch(Exception ex)
   {
       ExceptionManager.Add_Exception(TraceHelper.GetFuncName(), ex);
   } 
}
2.3 创建LoadProgram()函数

用于应用程序切换程序时导入视觉工具参数,这里只是举例说明读取注册图片

  /// <summary>
/// LoadProgram
 /// </summary>
 /// <param name="ProNO"></param>
 /// <returns></returns>
 public int LoadProgram(int ProNO)
 {
     int nRet = 0;
     try
     {
         //stp0  读取注册图片
         nRet = Read_Register_Img();
     }
     catch(Exception ex)
     {
         nRet = -2;
     }
     return nRet;
 }
 /***************************************************************/
 /// <summary>
 /// get_Path 
 /// 获取当前程序号的全路径
 /// </summary>
 /// <param name="proNO"></param>
 /// <returns></returns>
 private string  get_Path(int proNO)
 {
     return @appPath + "Program" + proNO.ToString("000") + "/";
 }
  /// <summary>
/// Read_CamParams
/// </summary>
/// <param name="CamNO"></param>
/// <returns></returns>
private int  Read_Register_Img(int CamNO)
{
    int nRet = 0;

    string CameraName, FilePath,  FileName;
    CameraName = CamNO.ToString();
    FilePath = get_Path(Program_NO)+"Cam" + CameraName+@"/";
    FileName = "camParams.xml";
    try
    {
        // 判断是否文件夹存在
        // 先清空内存
        BD_OperateSet.Assign_Temp(ref mat_buffers[CamNO,0],new Mat());
        // 读取保存的注册画面
        FileName = "Img.png";
        if (ContextManager.get_fileopCtx().FileExist(FilePath, FileName))
        { 
            Mat  tmp= Cv2.ImRead(FilePath + FileName, ImreadModes.Unchanged);
            BD_OperateSet.Assign_Mat(ref mat_buffers[CamNO, 0], ref tmp); 
            BD_OperateSet.Assign_Temp(ref tmp);// 清空临时变量
        } 
    }
    catch(Exception ex)
    {
        ExceptionManager.Add_Exception(TraceHelper.GetFuncName(), ex);
        nRet = (int)STATUS_ENUM.STATUS_EXCEPTION;
    } 
    return nRet;
}

/// <summary>
/// 读取全部相机注册图片
/// </summary>
/// <returns></returns>
private int Read_Register_Img()
{
    int nRet = 0;
    for(int i=0;i<n_max_CamCount;i++)
    {
        nRet = Read_Register_Img(i);
        if (nRet != 0) break;
    } 
    return nRet;
}

3 ContextManager中添加对VisionManager的实现

//visionManager
private static VisionManager vision_Ctx;
public static VisionManager get_visionCtx()
{
    if (vision_Ctx == null) vision_Ctx = new VisionManager();
    return vision_Ctx;
}

4 FormVision.exe 中实现

4.1 程序初始化时,导入程序参数
/// <summary>
/// Load_Program
/// 导入当前程序参数
/// </summary>
/// <param name="ProNO"></param>
/// <returns></returns>
private int   Load_Program( )
{
    int nRet = 0;
    ContextManager.get_visionCtx().LoadProgram(VisionManager.Program_NO);
    return nRet;
} 

Form_vision_Load时 ,按照以下流程进行处理

  1. 当前程序号赋值=0
  2. 导入程序参数
  3. 初始化显示控件
  4. 创建线程
private void Form_vision_Load(object sender, EventArgs e)
{
    //打开资源
    Open_Resources();
    // load 程序参数 
    VisionManager.Program_NO = 0;  
    // 导入程序参数
    Load_Program();
    // 初始化显示控件
    Init_Display();
    // 创建线程
    CreateThread();
    timer1.Interval = 100;
    timer1.Start();
}

Init_Display()实现

/// <summary>
/// Init_Display
/// 显示控件第一次显示, 目的进行画布的初始化布局
/// </summary>
private void  Init_Display()
{
    //显示控件第一次显示, 目的进行画布的初始化布局
    for(int i=0;i<VisionManager.n_max_CamCount;i++)
    {
        // 初始化显示注册图片,
        if(BD_OperateSet.MatisNotNull(ContextManager.get_visionCtx().mat_buffers[i,0]))
           bdDisplay_Runsets1.picture_cam.InitDisplay_Mat(ref ContextManager.get_visionCtx().mat_buffers[i, 0]);
    }
}
4.2 图片处理线程完善代码
  1. 取出最新图片 ,赋值给mat_buffer[1]
 //C# Class是地址传递,这里直接用=
  tmp = imgs_buffer.Pop_Front();
  //
  bdDisplay_Runsets1.flush_Display = false;
  int CamNO = 0;
  // stp0 matbuffer[CamNO,1],代表当前最新抓取图片
  BD_OperateSet.Assign_Mat(ref ContextManager.get_visionCtx().mat_buffers[CamNO, 1], ref tmp);
  ok_message.Add("采集图片成功");

在这里插入图片描述

  1. 彩色过滤处理,获取R通道图片

输入源mat_buffer[1],输出源mat_buffer[2]

 // stp1 cfilter 处理
 if (tmp.Type() == MatType.CV_8UC3)//判断是否彩色图片,一般采集图片都是8位的
   {
       Mat[] bgr = new Mat[3];
       // 分解成三通道, 默认是通道0:B ,通道1:G ,通道2: R
       Cv2.Split(tmp, out bgr);
       // 获取其中 R 通道,赋值给 mat_buffers[CamNO, 2]
       BD_OperateSet.Assign_Mat(ref ContextManager.get_visionCtx().mat_buffers[CamNO, 2], ref bgr[2]);
       // 销毁临时变量
       BD_OperateSet.Mats_Clear(bgr);
       bgr = null;

       ok_message.Add("彩色过滤器,获取R通道成功");
   }

在这里插入图片描述

  1. 灰度过滤处理,dst=src*scale+add; 输出到mat_buffer[7]

输入源mat_buffer[2],输出源mat_buffer[7]

// stp2  filter 处理
// 联系 scale  img 
 if (BD_OperateSet.MatisNotNull(ContextManager.get_visionCtx().mat_buffers[CamNO, 2]))
 {
     Mat scale_img = new Mat();
     // dst=src*1.2+add;
     double scale = 1.2;
     double add = 0;
     ContextManager.get_visionCtx().mat_buffers[CamNO, 2].ConvertTo(scale_img, -1, scale, add);
     //输出结果到 mat_buffers[CamNO, 6]
     BD_OperateSet.Assign_Mat(ref ContextManager.get_visionCtx().mat_buffers[CamNO, 7], ref scale_img);
     // 销毁临时变量
     BD_OperateSet.Assign_Temp(ref scale_img);
     ok_message.Add("灰度过滤器,图片增强成功");
 }

处理效果
在这里插入图片描述

  1. 视觉工具:Intensity,获取平均亮度
    输入源mat_buffer[7]
 // stp3  intensity处理
if (BD_OperateSet.MatisNotNull(ContextManager.get_visionCtx().mat_buffers[CamNO, 7]))
 {
     //获取平均亮度
     Scalar intensity = Cv2.Mean(ContextManager.get_visionCtx().mat_buffers[CamNO, 7]);
     ok_message.Add("获取图片平均亮度,亮度=" + intensity.Val0.ToString("0"));
 }

结果显示效果
在这里插入图片描述

  1. ImgProcessCCD 完整代码
/// <summary>
/// ImgProcessCCD0
///  remark: thread 图像process0
/// </summary>
private void ImgProcessCCD(int n_thread_index = 0)
{
   ListViewItem DATA = new ListViewItem();
   DateTime ts3 = DateTime.Now;   
   DateTime current = DateTime.Now;
   bool status = true;
   // OK结果信息记录
   List<string> ok_message = new List<string>();
   // NG结果信息记录
   List<string> ng_message = new List<string>();
   while ( newImgEvent_thread.WaitOne())   //相机1&2都已经已拍照
   {
       Mat tmp = null;
       ok_message.Clear();
       ng_message.Clear();
       try
       {  // 添加线程统计信息
          //C# Class是地址传递,这里直接用=
           tmp = imgs_buffer.Pop_Front();
           //
           bdDisplay_Runsets1.flush_Display = false;
           int CamNO = 0;
           // stp0 matbuffer[CamNO,1],代表当前最新抓取图片
           BD_OperateSet.Assign_Mat(ref ContextManager.get_visionCtx().mat_buffers[CamNO, 1], ref tmp);
           ok_message.Add("采集图片成功");
           // stp1 cfilter 处理
           if (tmp.Type() == MatType.CV_8UC3)//判断是否彩色图片,一般采集图片都是8位的
           {
               Mat[] bgr = new Mat[3];
               // 分解成三通道, 默认是通道0:B ,通道1:G ,通道2: R
               Cv2.Split(tmp, out bgr);
               // 获取其中 R 通道,赋值给 mat_buffers[CamNO, 2]
               BD_OperateSet.Assign_Mat(ref ContextManager.get_visionCtx().mat_buffers[CamNO, 2], ref bgr[2]);
               // 销毁临时变量
               BD_OperateSet.Mats_Clear(bgr);
               bgr = null;

               ok_message.Add("彩色过滤器,获取R通道成功");
           }
           // stp2  filter 处理
           // 联系 scale  img 
           if (BD_OperateSet.MatisNotNull(ContextManager.get_visionCtx().mat_buffers[CamNO, 2]))
           {
               Mat scale_img = new Mat();
               // dst=src*1.2+add;
               double scale = 1.2;
               double add = 0;
               ContextManager.get_visionCtx().mat_buffers[CamNO, 2].ConvertTo(scale_img, -1, scale, add);
               //输出结果到 mat_buffers[CamNO, 6]
               BD_OperateSet.Assign_Mat(ref ContextManager.get_visionCtx().mat_buffers[CamNO, 7], ref scale_img);
               // 销毁临时变量
               BD_OperateSet.Assign_Temp(ref scale_img);
               ok_message.Add("灰度过滤器,图片增强成功");
           }
           // stp3  intensity处理
           if (BD_OperateSet.MatisNotNull(ContextManager.get_visionCtx().mat_buffers[CamNO, 7]))
           {
               //获取平均亮度
               Scalar intensity = Cv2.Mean(ContextManager.get_visionCtx().mat_buffers[CamNO, 7]);
               ok_message.Add("获取图片平均亮度,亮度=" + intensity.Val0.ToString("0"));
           }
           // 图片结果刷新
           bdDisplay_Runsets1.flush_Display = true;
           if (BD_OperateSet.MatisNotNull(tmp))
           {
               int index = index_mat_buffer;
               if (index == -1) index = 1;
               switch (index_mat_buffer)
               {
                   case 0:
                       bdDisplay_Runsets1.Display(tmp);
                       break;
                   default:
                       bdDisplay_Runsets1.Display(ContextManager.get_visionCtx().mat_buffers[CamNO, index]);
                       break;
               }
             
           }
           else
           {
               status = false;
           }
           // 结果信息刷新
           bdDisplay_Runsets1.Display_Result(ok_message,ng_message,Color.DarkGreen,Color.Red);
          
           //统计结果显示
           thead0_summary.Update_Statistics(status);
           // 相机状态栏更新
           bdDisplay_Runsets1.Update_Cam_Text(status, thead0_summary.toString());
       }
       catch(Exception ex)
       {
           ExceptionManager.Add_Exception(TraceHelper.GetFuncName(), ex);
       }
       // 输出脉冲
       ContextManager.get_IOCtx().task_out_server_thread0.Add_One_Task(status); 
       // 临时变量赋值null
       tmp = null;
       if (StopProgramEvent.WaitOne(0, true)) break;
   } //end while 
   return;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1955178.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JSP内置对象及作用域

Request 存东西ResponseSession 存东西Application [ SerlvetContext ] 存东西config [ SerlvetConfig ]out/targetpage 不用了解exception <% page contentType"text/html;charsetUTF-8" language"java" %> <html> <head><title>…

从0到1搭建一个组件库

最近我开启了一个新项目&#xff0c;基于echarts进行二次封装&#xff0c;希望能为Vue3项目量身打造一套高效、易用的图表组件库&#xff0c;取名为 v-echarts。 目前雏形已经搭建完成&#xff0c;先把整个搭建过程做一个记录。后续再持续迭代、完善该图表组件库。 v-echarts 文…

微软现在允许开发人员对 Phi-3-mini 和 Phi-3-medium 模型进行微调

今年 4 月&#xff0c;微软首次发布了Phi-3 系列 SLM&#xff08;小型语言模型&#xff09;&#xff0c;该产品具有低成本、低延迟的特性。Phi-3-mini 是一种 3.8B 语言模型&#xff0c;有 4K 和 128K 两种上下文长度。Phi-3-medium 是 14B 语言模型&#xff0c;也有两种上下文…

解决git每次push代码到github都需要输入用户名以及密码

产生原因&#xff1a; 出现以上情况的主要原因在于采用的是 https 方式提交代码&#xff0c; 如果采用的是 ssh 方式只需要在版本库中添加用户的 sha 的key就可以实现提交时无需输入用户名和密码。 解决方法 在终端中使用以下命令删除原先已经建立的http的链接方式&#xff0c…

leetcode-79. 单词搜索

题目描述 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平相…

基于JSP、java、Tomcat三者的项目实战--校园交易网(3)主页

前文功能的实现 技术支持&#xff1a;JAVA、JSP 服务器&#xff1a;TOMCAT 7.0.86 编程软件&#xff1a;IntelliJ IDEA 2021.1.3 x64 前文三篇登录和注册功能的实现 基于JSP、java、Tomcat、mysql三层交互的项目实战--校园交易网&#xff08;1&#xff09;-项目搭建&#xf…

go 协程池的实现

使用场景 这次需求是做一个临时的数据采集功能&#xff0c;为了将积压的数据快速的消耗完&#xff0c;但是单一的脚本消耗的太慢&#xff0c;于是乎就手写了一个简单的协程池&#xff1a; 为了能加快数据的收集速度为了稳定协程的数量&#xff0c;让脚本变得稳定 设计图如下…

【JUC】线程局部变量ThreadLocal

文章目录 ThreadLocal简介面试题是什么&#xff1f;能干吗&#xff1f;API介绍initialValue方法&#xff08;不推荐&#xff09;withInitial方法&#xff08;推荐&#xff09;remove ThreadLocal入门案例原始需求需求变更线程池 总结 ThreadLocal源码分析Thread、ThreadLocal、…

区块链——hardhat使用

一、引入hardhat yarn add --dev hardhat // 引入验证合约的插件 yarn add --dev nomicfoundation/hardhat-verify 二、创建hardhat项目 yarn hardhat 三、编写我们的合约 四、编译我们的合约 yarn hardhat compile 五、编写脚本部署合约以及验证合约 // 获取hardhat环境对象 c…

Flutter大型项目架构:私有组件包管理

随着项目功能模块越来越多&#xff0c;怎么去管理这些私有组件包是一个不得不面对的问题&#xff0c;特别对于团队开发来讲&#xff0c;一些通用的公共组件往往会在多个项目间使用&#xff0c;多的有几十个&#xff0c;每个组件包都有有自己的版本&#xff0c;组件包之间还有依…

AI的欺骗游戏:揭示多模态大型语言模型的易受骗性

人工智能咨询培训老师叶梓 转载标明出处 多模态大型语言模型&#xff08;MLLMs&#xff09;在处理包含欺骗性信息的提示时容易生成幻觉式响应。尤其是在生成长响应时&#xff0c;仍然是一个未被充分研究的问题。来自 Apple 公司的研究团队提出了MAD-Bench&#xff0c;一个包含8…

漏洞复现-F6-11泛微-E-Cology-SQL

本文来自无问社区&#xff0c;更多漏洞信息可前往查看http://www.wwlib.cn/index.php/artread/artid/15575.html 0x01 产品简介 泛微协同管理应用平台e-cology是一套企业级大型协同管理平台 0x02 漏洞概述 该漏洞是由于泛微e-cology未对用户的输入进行有效的过滤&#xff0…

CentOS_7.9历史版本官网下载

文章目录 1. 官网下载1.1. 打开官网1.2. download1.3. Older Versions-click here1.4. RPMs1.5. Vault mirror1.6. 7.9.2009/1.7. isos1.8. x86_641.9. 选择安装包下载 2. 阿里云镜像站下载 1. 官网下载 下载地址(如果下载地址已失效&#xff0c;参考下面的步骤) iso是安装包…

【前端】一文带你了解 CSS

文章目录 1. CSS 是什么2. CSS 引入方式2.1 内部样式2.2 外部样式2.3 内联样式 3. CSS 常见选择器3.1 基础选择器3.1.1 标签选择器3.1.2 类选择器3.1.3 id 选择器3.1.4 通配符选择器 3.2 复合选择器3.2.1 后代选择器 4. CSS 常用属性4.1 字体相关4.2 文本相关4.3 背景相关4.4 设…

基于sklearn的机器学习 — 决策树与随机森林

基于树的学习算法是一种广泛而流行的非参数、有监督的分类和回归方法。 基于树的学习算法的基础是决策树&#xff08;decision tree&#xff09;&#xff0c;它将一系列决策规则串联起来&#xff0c;看起来像一棵倒立的树&#xff0c;第一条决策规则位于树顶&#xff0c;称之为…

第十四篇——军争篇:怎样在行军中设计战场

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 通过不利的战场&#xff0c;用方式方法&#xff0c;让战场逐渐转化成对自…

[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/140754278 出自【进步*于辰的博客】 参考笔记一&#xff0c;P10.4、P13.2&#xff1b;笔记三&am…

城市交通工具目标检测数据集自行车、公交车、小汽车、行人

数据整理不易&#xff0c;下载地址点这里&#xff1b; yolo格式数据集之交通工具检测5种&#xff1b; 数据集已划分好|可以直接使用|yolov5|v6|v7|v8|v9|v10通用&#xff1b; 本数据为交通工具检测检测数据集&#xff0c;数据集数量如下&#xff1a; 总共有:6633张 训练集&…

尚庭公寓(四)

房间基本属性管理共有五个接口&#xff0c;分别是**保存或更新属性名称**、**保存或更新属性值**、**查询全部属性名称和属性值列表**、**根据ID删除属性名称**、**根据ID删除属性值**。下面逐一是实现。 首先在AttrController中注入AttrKeyService和AttrValueService&#xf…

计数器与阻塞队列

目录 一&#xff1a;阻塞队列 模拟阻塞队列 二&#xff1a;线程池&#xff1a; 三&#xff1a;计数器&#xff1a; 定时器模拟实现 一&#xff1a;阻塞队列 阻塞队列是在原有的普通队列上做了扩充&#xff0c;标准库中原有的队列和子类都是线程不安全的。 1.线程安全 2.…