[图像处理] MFC OnMouseMove()绘制ROI矩形时的闪烁问题

2024-04-15 01:44

本文主要是介绍[图像处理] MFC OnMouseMove()绘制ROI矩形时的闪烁问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 问题
  • 对策
  • 代码
    • 完整工程
  • 结果
    • 使用Picture控件的RedrawWindow()的效果
    • 使用Dialog的RedrawWindow()的效果
    • 使用Picture控件的RedrawWindow(),ROI绘制到图像外的效果
  • 结论

问题

最近想通过业余时间,写一个简单的图像处理软件,一点点学习图像处理的基础知识。
目前想实现一个在图像上鼠标选取ROI矩形区域的功能。
想通过OnMouseMove()绘制一个随着鼠标拖动实时显示位置的矩形。

网上推荐双缓冲方案,但是怎么用MFC Picture控件和CImage实现双缓冲,还没查到。

目前采用了一个折中策略,虽然没有完全解决闪烁的问题,但是还可以接收。

对策

每次走进OnMouseMove(),调用Picture控件的RedrawWindow(),清空Piture控件区域,连同Image和ROI矩形一起清除。
重新把存在程序中的CImage Draw到Picture控件中。
通过OnMouseMove()传入的坐标,重画Roi矩形。
==不要调用Dialog的RedrawWindow,否则会严重闪烁。 ==

代码

void CGDITESTDlg::OnLButtonDown(UINT nFlags, CPoint point)
{ClientToScreen(&point);GetDlgItem(IDC_PIC_DISPLAY)->GetWindowRect(&rc_dsp);if (rc_dsp.PtInRect(point)) //判断鼠标左键落下时,point是否在控件的rect范围内{m_startPt = point; isStartPtValid = true;isDrawingRoi = true;isDrawRoiFinish = false;}CDialogEx::OnLButtonDown(nFlags, point);
}
void CGDITESTDlg::OnLButtonUp(UINT nFlags, CPoint point)
{ClientToScreen(&point);GetDlgItem(IDC_PIC_DISPLAY)->GetWindowRect(&rc_dsp);if (rc_dsp.PtInRect(point) && m_IsChoose)//判断鼠标左键抬起时,point是否在控件的rect范围内{if (isDrawingRoi && isStartPtValid){isDrawRoiFinish = false;isDrawingRoi = false;isStartPtValid = false;}}CDialogEx::OnLButtonUp(nFlags, point);
}
void CGDITESTDlg::OnMouseMove(UINT nFlags, CPoint point)
{if ((nFlags & MK_LBUTTON) == MK_LBUTTON)  //判断鼠标move的时候,鼠标左键是否按下{ClientToScreen(&point);GetDlgItem(IDC_PIC_DISPLAY)->GetWindowRect(&rc_dsp);if (rc_dsp.PtInRect(point) && isDrawingRoi) //判断鼠标左键落下时,point是否在控件的rect范围内{//就清空picture控件区域,重新画图片,这样就把原来的ROI消除了{CRect rc_dsp;m_ctl_pic_dsp.SetBitmap(NULL);GetDlgItem(IDC_PIC_DISPLAY)->GetWindowRect(&rc_dsp);ScreenToClient(&rc_dsp);//this->RedrawWindow(rc_dsp); //重绘主窗口指定区域 //使用这个函数,会重绘整个picture控件的rc_dsp区域,但是会引起严重闪烁m_ctl_pic_dsp.RedrawWindow(); //重绘主窗口指定区域 //使用这个控件,只会重绘图像区域,但是闪烁程度相对温柔(观察图片边缘仍可发现闪烁)//如果有绘制在picture控件内但是在图像外的线条,则不会被重绘CDC* pdc = nullptr;switch (m_IsChoose) //重绘image{case PIC_ORIGIN:pdc = m_ctl_pic_dsp.GetDC();image_origin.Draw(pdc->m_hDC, rc_convert);m_ctl_pic_dsp.ReleaseDC(pdc);break;case PIC_BINARIZATION:pdc = m_ctl_pic_dsp.GetDC();image_binarization.Draw(pdc->m_hDC, rc_convert);m_ctl_pic_dsp.ReleaseDC(pdc);break;case PIC_GREY:pdc = m_ctl_pic_dsp.GetDC();image_grey.Draw(pdc->m_hDC, rc_convert);m_ctl_pic_dsp.ReleaseDC(pdc);break;default:break;}}//画Rect{CRect rect;int rect_width = 0;int rect_height = 0;CPoint sel_pos;//GetCursorPos(&sel_pos);GetDlgItem(IDC_PIC_DISPLAY)->GetWindowRect(&rc_dsp);if (rc_dsp.PtInRect(point) && m_IsChoose && isStartPtValid && !isDrawRoiFinish)//判断鼠标左键抬起时,point是否在控件的rect范围内{//ClipCursor(&rc_dsp);//计算ROI的topleft和rightbottom坐标if (point.x > m_startPt.x)m_endPt.x = point.x < rc_dsp.right ? point.x : rc_dsp.right;elsem_endPt.x = point.x > rc_dsp.left ? point.x : rc_dsp.left;if (point.y > m_startPt.y)m_endPt.y = point.y < rc_dsp.bottom ? point.y : rc_dsp.bottom;elsem_endPt.y = point.y > rc_dsp.top ? point.y : rc_dsp.top;CPoint tplt, rtbt;tplt.x = m_startPt.x < m_endPt.x ? m_startPt.x : m_endPt.x;tplt.y = m_startPt.y < m_endPt.y ? m_startPt.y : m_endPt.y;rtbt.x = m_startPt.x > m_endPt.x ? m_startPt.x : m_endPt.x;rtbt.y = m_startPt.y > m_endPt.y ? m_startPt.y : m_endPt.y;m_ctl_pic_dsp.ScreenToClient(&tplt);m_ctl_pic_dsp.ScreenToClient(&rtbt);CDC* pDC = m_ctl_pic_dsp.GetWindowDC();CPen pen(PS_SOLID, 2, RGB(255, 0, 0));pDC->SelectStockObject(NULL_BRUSH);pDC->SelectObject(&pen);//在重新draw的image上再画矩形m_rc = CRect(tplt, rtbt);pDC->Rectangle(m_rc);}}}}CDialogEx::OnMouseMove(nFlags, point);
}

完整工程

MFC简单的图片处理工程

结果

使用Picture控件的RedrawWindow()的效果

在这里插入图片描述
可以看到,和图片接触的Picture控件边框会有闪烁,而图片部分本身没什么闪烁。
如果调整图像的Rect坐标,使其离开Picture控件的边框一点距离,会不会就没有闪烁了?

使用Dialog的RedrawWindow()的效果

在这里插入图片描述
这里是由于我采集GIf图的帧率太低(CSDN不能传超过5m的图),导致无法还原实际的闪烁效果。
实际上闪烁非常明显,但是没有这样大面积空白的情况。

使用Picture控件的RedrawWindow(),ROI绘制到图像外的效果

在这里插入图片描述
当ROI矩形,拉倒图像外但是还在Picture控件内的区域时,可以看到出现了异常的重叠矩形框,这些异常的矩形框无法随着新绘制ROI刷新掉。
我感觉Picture控件的RedrawWindow()只能重绘图像区。
这个问题可以通过控制ROI的坐标范围解决。

结论

仍然在探索双缓冲方案的实现。

这篇关于[图像处理] MFC OnMouseMove()绘制ROI矩形时的闪烁问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/904587

相关文章

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

opencv图像处理之指纹验证的实现

《opencv图像处理之指纹验证的实现》本文主要介绍了opencv图像处理之指纹验证的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录一、简介二、具体案例实现1. 图像显示函数2. 指纹验证函数3. 主函数4、运行结果三、总结一、

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

如何解决mysql出现Incorrect string value for column ‘表项‘ at row 1错误问题

《如何解决mysql出现Incorrectstringvalueforcolumn‘表项‘atrow1错误问题》:本文主要介绍如何解决mysql出现Incorrectstringv... 目录mysql出现Incorrect string value for column ‘表项‘ at row 1错误报错

如何解决Spring MVC中响应乱码问题

《如何解决SpringMVC中响应乱码问题》:本文主要介绍如何解决SpringMVC中响应乱码问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC最新响应中乱码解决方式以前的解决办法这是比较通用的一种方法总结Spring MVC最新响应中乱码解

pip无法安装osgeo失败的问题解决

《pip无法安装osgeo失败的问题解决》本文主要介绍了pip无法安装osgeo失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 进入官方提供的扩展包下载网站寻找版本适配的whl文件注意:要选择cp(python版本)和你py

解决Java中基于GeoTools的Shapefile读取乱码的问题

《解决Java中基于GeoTools的Shapefile读取乱码的问题》本文主要讨论了在使用Java编程语言进行地理信息数据解析时遇到的Shapefile属性信息乱码问题,以及根据不同的编码设置进行属... 目录前言1、Shapefile属性字段编码的情况:一、Shp文件常见的字符集编码1、System编码

Spring MVC使用视图解析的问题解读

《SpringMVC使用视图解析的问题解读》:本文主要介绍SpringMVC使用视图解析的问题解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC使用视图解析1. 会使用视图解析的情况2. 不会使用视图解析的情况总结Spring MVC使用视图