2.2.4 C#中显示控件BDPictureBox 的实现----ROI交互

2.2.4 C#中显示控件BDPictureBox 的实现----ROI交互

1 界面效果

在设定模式下,可以进行ROI 框的拖动,这里以Rect1举例说明
ROI 交互

2 增加ROI类定义

 /// <summary>
/// ROI_single
/// 用于描述图片感兴趣区域
/// type: 0:Rect1;1:Rect2;2:Circle ;3:Ellipse;4:Arc;5:Polygen;6:Point;7:line;
/// </summary>
public class ROI_single
{   //   Rect1 = 0,
    //    Rect2 = 1,
    //    Circle = 2,
    //    Ellipse = 3,
    //    Arc = 4,
    //    Polygen = 5,
    //    Point = 6,
    //    Line = 7 
    public int m_nType;
     // 参考labview  ROIdiscriptor
    public List<float> m_fDatas;
}

3 ROI生命周期示意图

ROI生命周期示意图

4 Button_Rect1 事件

创建或者显示ROI—Rect1矩形
btn_rect1

if (m_raw_mat != null)
{    // 更新原始图片数据
      Clear_Overlay_Internal();
      if (m_ROIs[m_ROI_index].m_nType != 0 || m_ROIs[m_ROI_index].m_fDatas.Count == 0)
      {
          // 如果主ROI 重画 ,Mask全部清空
          if (m_ROI_index == 0)
          {
              for (int i = 1; i < 5; i++) m_ROIs[i] = new ROI();
          }
          m_ROIs[m_ROI_index].m_nType = 0;
          m_ROIs[m_ROI_index].m_fDatas.Clear();
          //一般要求图片 大于30万像素
          m_ROIs[m_ROI_index].m_fDatas.Add((Single)m_raw_mat.Width / 4);
          m_ROIs[m_ROI_index].m_fDatas.Add((Single)m_raw_mat.Height / 4);
          m_ROIs[m_ROI_index].m_fDatas.Add((Single)3 * m_raw_mat.Width / 4);
          m_ROIs[m_ROI_index].m_fDatas.Add((Single)3 * m_raw_mat.Height / 4);
      }

      Disp_InterActive_ROIs_without_Update_Image(m_ROIs, MainColor_Roi, n_draw_ROI_thick); 
      m_ROI_draw_info.draw_mode = ROIDRAWMODE.NONE; 
  }

5 MouseDown选中ROI

这里以ROI_Rect1为例
mouseDown

private void pB_Display_MouseDown(object sender, MouseEventArgs e)
{
  if (e.Button == MouseButtons.Left && e.Clicks == 1)
  {
      try
      {
          lock (mutex_display)
          {
              m_MouseAction = 0;
              m_pLast.X = e.X;
              m_pLast.Y = e.Y;
              m_pCur.X = e.X;
              m_pCur.Y = e.Y; 

              OpenCvSharp.Point pt_img = DispManager.get_DispCTX().get_point_in_img(e.X, e.Y);
              float x_img = pt_img.X;
              float y_img = pt_img.Y;
              if (m_ROI_index != -1)
              {
                  if (!BD_Window_State_Judge()) return;
                  bd_window_state = BDDISPLAY_STATE.display_overlay;
                  // 进行交互画图
                  try
                  {
                      switch (m_ROItool_Type)
                      {
                          case 0: //none
                              m_MouseAction = ROI_MOUSE_ACTION.None;
                              break;
                          case ROITOOL_TYPE.PAN://pan mode
                              m_MouseAction = ROI_MOUSE_ACTION.DragImage;
                              break;
                          case ROITOOL_TYPE.RECT1:// rect1
                                 //step0: 判断 
                              if (m_ROIs[m_ROI_index].m_nType != 0 || m_ROIs[m_ROI_index].m_fDatas.Count == 0)
                              {
                                  m_ROI_draw_info.draw_mode = ROIDRAWMODE.NEWDRAW;
                                  m_ROIs[m_ROI_index].m_nType =(int)( m_ROItool_Type - 2);
                                  m_ROIs[m_ROI_index].m_fDatas.Add((Single)x_img);
                                  m_ROIs[m_ROI_index].m_fDatas.Add((Single)y_img);
                                  m_ROIs[m_ROI_index].m_fDatas.Add((Single)x_img);
                                  m_ROIs[m_ROI_index].m_fDatas.Add((Single)y_img);
                                  Disp_InterActive_ROIs_without_Update_Image(m_ROIs, MainColor_Roi, n_draw_ROI_thick);
                                  m_ROI_draw_info.selected_point_index = 1;// 默认第2个点
                                  m_ROI_draw_info.draw_mode = ROIDRAWMODE.DRAGPOINT;
                                  m_MouseAction = ROI_MOUSE_ACTION.DragROI;
                                  break;
                              }
                              if (m_ROIs[m_ROI_index].m_nType == 0 && m_ROIs[m_ROI_index].m_fDatas.Count == 4) //rect
                              {
                                  // 2.1 判断key point是否选中
                                  m_ROI_draw_info.selected_point_index = get_interactive_key_draw_point((int)x_img, (int)y_img); ;
                                  switch (m_ROI_draw_info.selected_point_index)
                                  {
                                      case 0:
                                          m_ROI_draw_info.draw_mode = ROIDRAWMODE.DRAGPOINT; 
                                          break;
                                      case 1:
                                          m_ROI_draw_info.draw_mode = ROIDRAWMODE.DRAGPOINT; 
                                          break;
                                      case 2:
                                          m_ROI_draw_info.draw_mode = ROIDRAWMODE.SHIFTROI; 
                                          break;
                                      case -1:
                                          m_ROI_draw_info.draw_mode = 0;
                                          break;
                                      default:
                                          m_ROI_draw_info.draw_mode = 0;
                                          break;
                                  }
                                  m_MouseAction = ROI_MOUSE_ACTION.DragROI;
                                  break;
                              }
                              break;
                          default:
                              break;
                      }
                      if (m_MouseAction == ROI_MOUSE_ACTION.DragROI)
                      {
                          Clear_Extract_Zoom_Overlay();
                          // 后续可以改善成 只清除局部区域 
                      }
                  }
                  catch (Exception ex)
                  {
                      m_MouseAction = ROI_MOUSE_ACTION.None;
                      label_img_info.Text = "Mouse Down:" + ex.Message;
                  }
                  // 保存 old ROIs clear用
                  m_old_ROIs = m_ROIs;
                  bd_window_state = BDDISPLAY_STATE.idle;
              }
          }
      }
      catch (Exception ex)
      {
          m_MouseAction = ROI_MOUSE_ACTION.None;
          label_img_info.Text = "Mouse Down:" + ex.Message;
      }
  }
}
       

6 MouseMove 拖动ROI

鼠标拖动ROI的某个关键点或者整体平移ROI
mousemove

private void pB_Display_MouseMove(object sender, MouseEventArgs e)
{
   // 2022 08 13 改善 pan img 图片很大时 迟钝 ,mouse move的频率看起来比 hscr 要快 
   if (m_MouseAction == ROI_MOUSE_ACTION.DragImage)
   {
       double t_gap = DateTime.Now.Subtract(_last_pan).TotalMilliseconds;
       if (t_gap < 40) return;
   }

   double m_rvalue, m_gvalue, m_bvalue;
   float x_img, y_img;
   int nRet = 0;
   try
   {
       if (!BD_OperateSet.MatisNotNull(m_raw_mat)) return;
       lock (mutex_display)
       {
           if (m_MouseAction != ROI_MOUSE_ACTION.None)
           {
               if ((m_MouseAction != ROI_MOUSE_ACTION.DragImage && m_MouseAction != ROI_MOUSE_ACTION.DragROI) || !BD_Window_State_Judge()) return;
               bd_window_state = BDDISPLAY_STATE.mouse_drag;

               try
               {
                   if (m_MouseAction != ROI_MOUSE_ACTION.WheelImage && e.Button == MouseButtons.Left)// 只有鼠标左键可以drag
                   {
                       // 只有两种情况 dragimg 或者 dragROI 
                       if (m_MouseAction == ROI_MOUSE_ACTION.DragImage || m_MouseAction == ROI_MOUSE_ACTION.DragROI)
                       {
                           lock (mutex_display)
                           {
                               m_pCur.X = e.X;
                               m_pCur.Y = e.Y;
                               m_pDist_mouse.X = (int)(m_pCur.X - m_pLast.X);
                               m_pDist_mouse.Y = (int)(m_pCur.Y - m_pLast.Y);
                               m_pDist_img = DispManager.get_DispCTX().get_mousemove_shift_in_ccs(m_pDist_mouse);
                               switch (m_ROItool_Type)
                               {
                                   case 0:// none
                                       break;
                                   case ROITOOL_TYPE.PAN:// pan
                                       {
                                           DispManager.get_DispCTX().update_Scroll_Info_after_pan(m_pDist_mouse);
                                           update_ExtractRGB_and_NewOverlay();
                                           //更新显示
                                           Flush_Overlay_to_Display();
                                       }
                                       break;
                                   default:
                                       switch (m_ROI_draw_info.draw_mode)
                                       {
                                           case 0://  none
                                               break;
                                           case ROIDRAWMODE.NEWDRAW:// new draw
                                               break;
                                           case ROIDRAWMODE.DRAGPOINT: // dragon
                                           case ROIDRAWMODE.SHIFTROI: // shift 
                                               {
                                                   Clear_InterActive_ROIs(m_old_ROIs, Black, n_draw_ROI_thick);
                                                   drag_interactive_ROI(m_pDist_img.X, m_pDist_img.Y);
                                                   Disp_InterActive_ROIs_without_Update_Image(m_ROIs, MainColor_Roi, n_draw_ROI_thick);
                                                 
                                               }
                                               break;
                                           default:
                                               break;
                                       }
                                       break;
                               }
                               // 保存 old ROIs clear用
                               m_old_ROIs = m_ROIs;
                           }
                       }
                       // 这里更新 m_pLast 是因为 ROI 更新时 也是实时更新 ROI 的数据的
                       // 如果改成 Roi_last 一直不变 ,然后显示临时ROI ,这样 就可以不用更新m_pLast, 这样会更加准确
                       switch (m_ROItool_Type)
                       {
                           case ROITOOL_TYPE.PAN:// pan
                               m_pLast.X = m_pCur.X;
                               m_pLast.Y = m_pCur.Y;
                               break;
                           default:
                               m_pLast.X = m_pCur.X;
                               m_pLast.Y = m_pCur.Y;
                               break;
                       }
                   }
               }
               catch (Exception ex)
               {
                   label_img_info.Text = "MouseMove:" + ex.Message;
               }
               bd_window_state = BDDISPLAY_STATE.idle; 
           }
           //if (m_MouseAction == ROI_MOUSE_ACTION.None) //  空余时间 显示图像信息
           else
           {
               // disp img info
               // 参考以前代码源程序
           }
       }
   }
   catch (Exception ex)
   {
       label_img_info.Text = "MouseMove:" + ex.Message;
   }

   _last_pan = DateTime.Now;
}
        

6 MouseUp事件

标志位复位
m_ROI_draw_info.draw_mode = 0;
m_ROI_draw_info.selected_point_index = -1;

7 未完待续,后续会附上新增的源代码

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SQL Server数据库的组成

《SQL Server 2022从入门到精通&#xff08;视频教学超值版&#xff09;》图书介绍-CSDN博客 对于数据库的概念&#xff0c;没有一个完全固定的定义&#xff0c;随着数据库历史的发展&#xff0c;定义的内容也有很大的差异&#xff0c;其中一种比较普遍的观点认为&#xff0c;…

Java - 程序员面试笔记记录 实现 - Part1

社招又来学习 Java 啦&#xff0c;这次选了何昊老师的程序员面试笔记作为主要资料&#xff0c;记录一下一些学习过程。 1.1 Java 程序初始化 Java 程序初始化遵循规则&#xff1a;静态变量优于动态变量&#xff1b;父类优于子类&#xff1b;成员变量的定义顺序&#xff1b; …

使用TensorFlow进行OCR识别:将表格图片转换为结构化数据

随着人工智能和机器学习技术的不断发展&#xff0c;OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;技术已经成为处理图像中文本信息的强大工具。TensorFlow是一个广泛使用的开源机器学习框架&#xff0c;它提供了丰富的API和工具&#xff…

【源码 +文档+调试讲解】大学生企业推荐系统ssm

大学生企业推荐系统采用B/S结构、java开发语言、以及Mysql数据库等技术。系统主要分为管理员和学生、企业三部分&#xff0c;管理员主要功能包括&#xff1a;首页、个人中心、学生管理、企业管理、招聘信息管理、个人简历管理、应聘职位管理、评价企业管理、交流论坛、系统管理…

IDEA中Maven的配置

目录 1. 安装maven 2. 配置环境变量 3. IDEA中配置Maven 4. 配置仓库目录 1. 安装maven 官网下载地址&#xff1a;Maven – Download Apache Maven 下载后&#xff0c;将zip压缩包解压到某个目录即可。 2. 配置环境变量 变量名称随意&#xff0c;通常为M2_HOME&#xff…

双向广搜——AcWing 190. 字串变换

双向广搜 定义 双向广度优先搜索&#xff08;Bi-directional Breadth-First Search, Bi-BFS&#xff09;是一种在图或树中寻找两点间最短路径的算法。与传统的单向广度优先搜索相比&#xff0c;它从起始点和目标点同时开始搜索&#xff0c;从而有可能显著减少搜索空间&#x…

【MindSpore学习打卡】应用实践-计算机视觉-FCN图像语义分割-基于MindSpore实现FCN-8s进行图像语义分割的教程

图像语义分割是计算机视觉领域中的一个重要任务&#xff0c;它旨在对图像中的每个像素进行分类&#xff0c;从而实现对图像内容的详细理解。在众多图像语义分割算法中&#xff0c;全卷积网络&#xff08;Fully Convolutional Networks, FCN&#xff09;因其端到端的训练方式和高…

vlan基础相关

7.2以太网交换基础 数据链路层也叫2层网络&#xff0c;用的是Mac地址&#xff0c;想到Mac地址就要想到交换机。 以太网协议&#xff08;LAN&#xff09;以太网是建立在CSMA/CD载波监听多路访问/冲突检测&#xff0c;机制上的广播型网络。CSMA工作原理是先监听&#xff0c;在介…

宇宙第一大厂亚马逊云科技AWS人工智能/机器学习证书即将上线,一篇文章教你轻松拿下

据麦肯锡《在华企业如何填补AI人才缺口》研究表明&#xff0c;到2030年人工智能为中国带来的潜在价值有望超过1万亿美元&#xff0c;而随着各大企业进入人工智能化&#xff0c;对该领域的人才需求将从目前的100万增长到2030年的600万。然而到保守估计&#xff0c;到2030可以满足…

「实战应用」如何用图表控件LightningChart JS创建SQL仪表板应用(三)

LightningChart JS是Web上性能特高的图表库&#xff0c;具有出色的执行性能 - 使用高数据速率同时监控数十个数据源。 GPU加速和WebGL渲染确保您的设备的图形处理器得到有效利用&#xff0c;从而实现高刷新率和流畅的动画&#xff0c;常用于贸易&#xff0c;工程&#xff0c;航…

WPS-Word文档表格分页

一、问题描述 这种情况不好描述 就是像这种表格内容&#xff0c;但是会有离奇的分页的情况。这种情况以前的错误解决办法就是不断地调整表格的内容以及间隔显得很乱&#xff0c;于是今天去查了解决办法&#xff0c;现在学会了记录一下避免以后忘记了。 二、解决办法 首先记…

PLC_博图系列☞F_TRIG:检测信号下降沿

PLC_博图系列☞F_TRIG&#xff1a;检测信号下降沿 文章目录 PLC_博图系列☞F_TRIG&#xff1a;检测信号下降沿背景介绍F_TRIG&#xff1a; 检测信号下降沿说明参数示例 关键字&#xff1a; PLC、 西门子、 博图、 Siemens 、 F_TRIG 背景介绍 这是一篇关于PLC编程的文章&a…

中南大学湘雅三院张如旭/刘爱华团队发现牙髓干细胞来源的外泌体减轻脑缺血再灌注损伤的神经保护机制

随着我国人口老龄化的加剧&#xff0c;中风已成为我国主要的公共卫生疾病之一&#xff0c;确定其潜在的分子机制和治疗靶点对于开发有效的预防和治疗策略至关重要。近期&#xff0c;中南大学湘雅第三医院张如旭、刘爱华团队在经典权威期刊《Pharmacological Research》&#xf…

从一次 SQL 查询的全过程了解 DolphinDB 线程模型

1. 前言 DolphinDB 的线程模型较为复杂&#xff0c;写入与查询分布式表都可能需要多个类型的线程。通过了解 SQL 查询的全过程&#xff0c;可以帮助我们了解 DolphinDB 的线程模型&#xff0c;掌握 DolpinDB 的配置&#xff0c;以及优化系统性能的方法。 本教程以一个分布式 …

华清远见人工智能课程:项目优势助力,学习更高效!

在人工智能飞速发展的今天&#xff0c;学习人工智能成为新的高薪赛道。我们都知道人工智能的学习离不开项目练手&#xff0c;只有通过实际项目的操作&#xff0c;才能真正掌握人工智能的核心技能。但遗憾的是&#xff0c;很多人工智能课程只注重理论知识的传授&#xff0c;缺乏…

WEB项目通过浏览器打开windows上的exe应用

一、背景 最近有一个新需求&#xff0c;是通过浏览器打开本地exe应用。因为我们公司的产品是以exe为主&#xff0c;用web项目管理数据&#xff0c;接到的新项目是web为企业门户需要集成所有的应用&#xff0c;前端通过按钮点击打开本地exe应用。一开始还有点懵&#xff0c;因为…

Coze 国际版停止免费开启商业化

昨晚 Coze 国际版没有任何官方通知&#xff0c;悄悄开启了 Premium 服务&#xff0c;API 和 SDK 调用不再免费。 免费版只提供每日 10 条消息&#xff0c;最低的 9 刀套餐&#xff0c;每日最多 100 条消息&#xff0c;GPT-4o 最多 10 条。 国内版目前还是免费的&#xff0c;但…

大数据之FlinkCDC

最近在做FLinkCDC数据实时同步的数据抽取处理 目标: 将源端系统Oracle数据库的实时数据通过FLINKCDC的形式抽取到Doris中 问题: 在抽取的过程中,如果表的数据量太大,抽取超过30张表以后,所有的任务大概运行25~30分钟以后,所有的任务的状态会从running 变为 Failed. 解决方案…

BitLocker 的作用是什么?如何开启或者关闭它?

BitLocker 是什么 BitLocker 是一种全盘加密&#xff08;FDE&#xff09;技术&#xff0c;最早在 Windows Vista 中引入&#xff0c;并在后续版本的 Windows 中得到了持续改进。BitLocker 使用高级加密标准&#xff08;AES&#xff09;来加密整个磁盘分区&#xff0c;确保只有…