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 未完待续,后续会附上新增的源代码

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

V言微语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值