2.5 C#视觉程序开发实例2----图片内存管理 Csharp实现
创始人
2024-11-21 01:08:08
0

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()函数

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

  ///  /// LoadProgram  ///   ///   ///   public int LoadProgram(int ProNO)  {      int nRet = 0;      try      {          //stp0  读取注册图片          nRet = Read_Register_Img();      }      catch(Exception ex)      {          nRet = -2;      }      return nRet;  }  /***************************************************************/  ///   /// get_Path   /// 获取当前程序号的全路径  ///   ///   ///   private string  get_Path(int proNO)  {      return @appPath + "Program" + proNO.ToString("000") + "/";  }   ///  /// Read_CamParams ///  ///  ///  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; }  ///  /// 读取全部相机注册图片 ///  ///  private int Read_Register_Img() {     int nRet = 0;     for(int i=0;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 程序初始化时,导入程序参数
///  /// Load_Program /// 导入当前程序参数 ///  ///  ///  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()实现

///  /// Init_Display /// 显示控件第一次显示, 目的进行画布的初始化布局 ///  private void  Init_Display() {     //显示控件第一次显示, 目的进行画布的初始化布局     for(int i=0;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 完整代码
///  /// ImgProcessCCD0 ///  remark: thread 图像process0 ///  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 ok_message = new List();    // NG结果信息记录    List ng_message = new List();    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; } 

相关内容

热门资讯

第3分钟了解!微扑克发牌为什么... 第3分钟了解!微扑克发牌为什么这么离谱,沐沐福建麻将十三水分析器,2025新版(有人有挂)-哔哩哔哩...
黑科技ai(鱼扑克辅助)德扑线... 黑科技ai(鱼扑克辅助)德扑线上素来真的是有挂!太实锤了都是是真的有挂(2022已更新)(哔哩哔哩)...
7分钟了解!aa扑克有外挂吗,... 7分钟了解!aa扑克有外挂吗,邳州友友麻将有假吗,必胜教程(有挂技巧)-哔哩哔哩1、完成邳州友友麻将...
黑科技了解(德扑之星解析)云扑... 黑科技了解(德扑之星解析)云扑克cloudpoker一贯真的是有挂!太嚣张了一向真的是有挂(2020...
第七分钟了解!wpk机器人代打... 第七分钟了解!wpk机器人代打,胡乐麻将辅牌器怎么下载,揭秘教程(有挂细节)-哔哩哔哩1)胡乐麻将辅...
黑科技实锤(aapoker a... 1、黑科技实锤(aapoker app)德州机器人素来有挂!太无语了一向是有挂(2025已更新)(哔...
辅助黑科技(WPK app)x... 辅助黑科技(WPK app)x-poker原本真的是有挂!太无语了从来是真的有挂(2025已更新)(...
三分钟了解!智星德州菠萝怎么开... 三分钟了解!智星德州菠萝怎么开挂,一起跑得快吗,黑科技教程(有挂秘笈)-哔哩哔哩1、进入到智星德州菠...
5分钟了解!wepoke用什么... 5分钟了解!wepoke用什么模拟器,约战荆门手机麻将输赢概率技巧,黑科技教程(有挂解密)-哔哩哔哩...
黑科技规律(WPK程序)微扑克... 黑科技规律(WPK程序)微扑克机器人原来真的是有挂!太坑了总是真的是有挂(2021已更新)(哔哩哔哩...