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  ROIdiscriptorpublic 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: //nonem_MouseAction = ROI_MOUSE_ACTION.None;break;case ROITOOL_TYPE.PAN://pan modem_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:// nonebreak;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://  nonebreak;case ROIDRAWMODE.NEWDRAW:// new drawbreak;case ROIDRAWMODE.DRAGPOINT: // dragoncase 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:// panm_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.mzph.cn/web/38568.shtml

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

相关文章

工业路由器与家用路由器的区别

在现代网络环境中&#xff0c;路由器扮演着至关重要的角色。无论是在家庭网络还是在工业网络&#xff0c;选择合适的路由器都至关重要。本文将从多个角度&#xff0c;对工业路由器与家用路由器进行详细比较&#xff0c;帮助您更好地理解二者的区别。 1、安全性 工业路由器&…

大模型应用开发实战基础

大模型应用开发实战基础 1. 背景 大模型如日中天&#xff0c;各行各业都受它影响&#xff0c;但是作为程序员&#xff0c;除了让它翻译代码不知道用它干什么&#xff0c;就像是拿着锤子的木匠&#xff0c;找不到钉子在哪。一边听着别人说2024是AI元年&#xff0c;一边又不知所…

中控室监控台在水处理行业的作用

随着工业化和城市化的快速推进&#xff0c;水处理行业的重要性日益凸显。作为确保水质安全、提高水资源利用效率的关键环节&#xff0c;水处理厂需要高效、稳定地运行。在这个过程中&#xff0c;中控室监控台发挥着不可或缺的作用。本文将从以下几个方面&#xff0c;详细阐述中…

fyne的MultiLineEntry设置大小

MultiLineEntry设置大小 在另一篇文章讲过&#xff0c;放入border布局中&#xff0c;可以最大化MultiLineEntry。 这里再介绍另一种方法:SetMinRowsVisible() func (e *Entry) SetMinRowsVisible(count int) {e.multiLineRows counte.Refresh() }SetMinRowsVisible强制mult…

九浅一深Jemalloc5.3.0 -- ④浅*配置

目前市面上有不少分析Jemalloc老版本的博文&#xff0c;但最新版本5.3.0却少之又少。而且5.3.0的架构与5之前的版本有较大不同&#xff0c;本着“与时俱进”、“由浅入深”的宗旨&#xff0c;我将逐步分析最新release版本Jemalloc5.3.0的实现。 另外&#xff0c;单讲实现代码是…

ShareSDK iOS端如何实现小红书分享

下载SDK 请登陆官网 &#xff0c;找到SDK下载&#xff0c;勾选需要的平台下载 导入SDK &#xff08;1&#xff09;离线导入将上述下载到的SDK&#xff0c;直接将整个SDK资源文件拖进项目里&#xff0c;如下图&#xff1a; 并且勾选以下3个选项 在点击Finish&#xff0c;…

JavaSE简易版扫雷小游戏

描述&#xff1a;用户输入二维雷区的高和宽&#xff0c;输入确定地雷数&#xff0c;随机在地雷区生成地雷。用户输入横竖坐标进行挖雷&#xff0c;挖到地雷游戏以失败结束&#xff0c;并让用户选择是否再次游戏&#xff1b;没挖到雷&#xff0c;显示该区域8个方向地雷数。如果8…

uniapp + vue3 + Script Setup 写法变动 (持续更新)

一、uniapp 应用生命周期&#xff1a; https://uniapp.dcloud.net.cn/tutorial/vue3-composition-api.html 注意&#xff1a; 应用生命周期仅可在App.vue中监听&#xff0c;在其它页面监听无效。 二 、uniapp页面生命周期&#xff1a; https://uniapp.dcloud.net.cn/tutori…

Golang | Leetcode Golang题解之第212题单词搜索II

题目&#xff1a; 题解&#xff1a; type Trie struct {children map[byte]*Trieword string }func (t *Trie) Insert(word string) {node : tfor i : range word {ch : word[i]if node.children[ch] nil {node.children[ch] &Trie{children: map[byte]*Trie{}}}nod…

Zynq系列FPGA实现SDI视频编解码,基于GTX高速接口,提供5套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案在Xilinx--Kintex系列FPGA上的应用 3、详细设计方案设计原理框图SDI 输入设备Gv8601a 均衡器GTX 解串与串化SMPTE SD/HD/3G SDI IP核BT1120转RGB图像缓存视频读取控制HDMI输出RGB转BT1120Gv8500 驱…

vuepress使用简介及个人博客搭建

目录 一、介绍二、环境准备三、安装运行vuepress四、目录结构五、配置文件六、导航栏配置七、导航栏logo八、浏览器图标九、侧边栏配置十、添加 Git 仓库和编辑链接十一、部署到GitHub十二、搭建成功 一、介绍 VuePress 是 Vuejs 官方提供的一个是Vue驱动的静态网站生成器&…

Qt 配置ASan

Qt 配置ASan 文章目录 Qt 配置ASan摘要关于ASan&#xff08;AddressSanitizer&#xff09;在Qt中配置 ASan1. 安装必要的工具2. 修改项目的 .pro 文件3. 重新构建项目4. 运行应用程序5. 分析错误报告示例注意事项 关键字&#xff1a; Qt、 ASan、 AddressSanitizer 、 GCC …

CTFHUB-SSRF-Redis协议

本题需要用到&#xff1a; 在线编码网址&#xff1a;https://icyberchef.com/ gopherus工具&#xff1a;https://mp.csdn.net/mp_blog/creation/editor/139440201 开启题目&#xff0c;页面空白 和上一个题FastCGI协议一样&#xff0c;还是使用gopherus攻击redis ./gopheru…

vlan基础相关

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

110kV以下变电所电力监控-安科瑞电力监控解决方案

一、系统介绍 变电站电力监控系统为110kV及以下用户变电站提供了完整的SCADA功能。 二、系统硬件 AM5SE系列微机保护装置 全电参量测量 谐波制动独立操作回路 可编程出口矩阵&#xff1b;定制化的逻辑设计&#xff1b;故障录波&#xff1b;事件记录、故障 录波数据&#x…

聊天交友系统开发专业语聊交友app开发搭建同城交友开发婚恋交友系统相亲app开发

1、上麦相亲互动:直播间内除了红娘外&#xff0c;还有男女用户两个视频麦位&#xff0c;直播间符合要求的用户可以申请上麦 2、公屏聊天:为上麦用户可以通过在公屏发言的方式参与直播间内的话题互动。 3、私信,异性用户之间可以发送私信消息&#xff0c;通过付费或开通会员可解…

法国工程师IMT联盟 密码学及其应用 2023年期末考试补考题

1 JAVA 安全 1.1 问题1 1.1.1 问题 用 2 或 3 句话解释 Java 执行模型&#xff08;Java 虚拟机machine virtuelle Java)&#xff09;中引入introduit沙箱bac sable机制 mcanisme d’excution par isolation的目的。 1.1.2 问题解释 在 Java 执行模型&#xff08;Java 虚拟机…

Java面试八股文

一、Redis 1. 使用场景 &#xff08;1&#xff09;Redis的数据持久化策略有哪些 RDB&#xff1a;全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c;也被叫作Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故…

【信息系统项目管理师】18年~23年案例概念型知识

文章目录 18上18下19上19下20上20下21上21下22年上22年下23年上 18上 请简述 ISO 9000 质量管理的原则 领导作用、 过程方法、 管理的系统方法、 与供方互利的关系、 基于事实的决策方法、 持续改进、 全员参与、 以顾客为关注焦点 概念 国家标准(GB/T 1 9000 2008)对质量的定…

嵌入式c语言2——预处理

在c语言中&#xff0c;头部内容&#xff0c;如include与define是不参与编译而直接预先处理的 如include相当于把头文件扩展&#xff0c;define相当于做了替换 c语言大型工程创建时&#xff0c;会有调试版本与发行版本&#xff0c;发行时不希望看到调试部分内容&#xff0c;此时…