您的位置:首页 > 科技 > IT业 > 2.5 C#视觉程序开发实例2----图片内存管理 Csharp实现

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

2024/10/7 4:33:41 来源:https://blog.csdn.net/weixin_42490025/article/details/140754461  浏览:    关键词:2.5 C#视觉程序开发实例2----图片内存管理 Csharp实现

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_buffersmat_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: RCv2.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: RCv2.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); // 临时变量赋值nulltmp = null;if (StopProgramEvent.WaitOne(0, true)) break;} //end while return;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com