[图像处理] MFC载入图片并进行二值化处理和灰度处理及其效果显示

本文主要是介绍[图像处理] MFC载入图片并进行二值化处理和灰度处理及其效果显示,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 工程效果
  • 重要代码
  • 完整代码
  • 参考

工程效果

载入图片,并在左侧显示原始图片、二值化图片和灰度图片。
双击左侧的图片控件,可以在右侧的大控件中,显示双击的图片。

初始画面:
在这里插入图片描述
载入图片:
在这里插入图片描述
双击左侧的第二个控件,显示图片:
在这里插入图片描述
//对图片显示在控件中的位置没有进行优化。

重要代码

主要是用的MFC Image控件。

载入图片:

void CGDITESTDlg::OnBnClickedBtnStart()
{//获取图像文件CFileDialog filedlg(TRUE,_T("png"),NULL,0,TEXT("image Files(*.bmp;*.jpg;*.png)|*.bmp;*.jpg;*.png|all files(*.*)|(*.*)||"),this);filedlg.DoModal();m_cstr_filepath = filedlg.GetPathName();m_cstr_filename = filedlg.GetFileName();if (m_cstr_filepath.IsEmpty() || m_cstr_filename.IsEmpty()){AfxMessageBox(TEXT("打开文件失败"));return ;}	image_origin.Load(m_cstr_filepath);image_binarization.Load(m_cstr_filepath);image_grey.Load(m_cstr_filepath);//获取图像尺寸imgw = image_origin.GetWidth();imgh = image_origin.GetHeight();img_t = imgw / imgh;//根据图像尺寸,调整控件客户区尺寸比例CRect rect_ctl;m_ctl_pic_origin.GetClientRect(&rect_ctl);float rectw = rect_ctl.Width();float recth = rect_ctl.Height();float rect_t = rectw / recth;if(rect_t < img_t){rect_ctl = CRect(rect_ctl.TopLeft(), CSize(rect_ctl.Width(), rect_ctl.Width() / img_t ));}else{rect_ctl = CRect(rect_ctl.TopLeft(), CSize(rect_ctl.Height() * img_t, rect_ctl.Height()));}//显示图像到控件客户区CDC* pdc = m_ctl_pic_origin.GetDC();m_ctl_pic_origin.SetBitmap(NULL);	image_origin.Draw(pdc->m_hDC, rect_ctl);//图像二值化处理ImageBinarizationProcess(image_binarization);//根据图像尺寸,调整控件客户区尺寸比例CRect rect_ctl_binarization;m_ctl_pic_binarization.GetClientRect(&rect_ctl_binarization);float rectw_ = rect_ctl_binarization.Width();float recth_ = rect_ctl_binarization.Height();float rect_t_ = rectw / recth;if (rect_t_ < img_t){rect_ctl_binarization = CRect(rect_ctl_binarization.TopLeft(), CSize(rect_ctl_binarization.Width(), rect_ctl_binarization.Width() / img_t));}else{rect_ctl_binarization = CRect(rect_ctl_binarization.TopLeft(), CSize(rect_ctl_binarization.Height() * img_t, rect_ctl_binarization.Height()));}//显示图像到控件客户区CDC* pdc_ = m_ctl_pic_binarization.GetDC();m_ctl_pic_binarization.SetBitmap(NULL);image_binarization.Draw(pdc_->m_hDC, rect_ctl_binarization);//图像灰度处理ImageGreyProcess(image_grey);//根据图像尺寸,调整控件客户区尺寸比例CRect rect_ctl_grey;m_ctl_pic_grey.GetClientRect(&rect_ctl_grey);float rectw__ = rect_ctl_grey.Width();float recth__ = rect_ctl_grey.Height();float rect_t__ = rectw / recth;if (rect_t__ < img_t){rect_ctl_grey = CRect(rect_ctl_grey.TopLeft(), CSize(rect_ctl_grey.Width(), rect_ctl_grey.Width() / img_t));}else{rect_ctl_grey = CRect(rect_ctl_grey.TopLeft(), CSize(rect_ctl_grey.Height() * img_t, rect_ctl_grey.Height()));}//显示图像到控件客户区CDC* pdc__ = m_ctl_pic_grey.GetDC();m_ctl_pic_grey.SetBitmap(NULL);image_grey.Draw(pdc__->m_hDC, rect_ctl_grey);isLoadedImage = true;m_ctl_pic_origin.ReleaseDC(pdc);m_ctl_pic_binarization.ReleaseDC(pdc);m_ctl_pic_grey.ReleaseDC(pdc);
}

图像二值化处理:
算法来源:C++MFC打开图片、彩图,以及对图像进行简单算法处理

void CGDITESTDlg::ImageBinarizationProcess(CImage &image)
{BYTE* pimagedata = (BYTE*)image.GetBits();	//获取到图片内存点的位置int width = image.GetWidth();int height = image.GetHeight();int pit = image.GetPitch();//图像每行字节数int bytes_per_pixel = image.GetBPP() / 8; //获取每像素的位数除以8得到每个像素占的字节数std::vector<int> gray(256); //初始化时自动存0,用来存放256种颜色出现的次数for (int i = 0; i < height; i++){for (int j = 0; j < width; j++){gray.at((int)*(pimagedata + pit * i + bytes_per_pixel * j)) += 1;}}int max = 0;int sec = 0;int localmax = 0;int localsec = 0;for (int i = 0; i < 256; i++){if (gray[i] > max){max = gray[i];localmax = i;}}for (int i = 0; i < 256; i++){if (gray[i] > sec && abs(i - localmax) > 10){sec = gray[i];localsec = i;}}int mid = (localmax + localsec) / 2;for (int i = 0; i < height; i++){for (int j = 0; j < width; j++){if ((int)(*(pimagedata + pit * i + j * bytes_per_pixel)) < mid){*(pimagedata + pit * i + j * bytes_per_pixel) = 0;*(pimagedata + pit * i + j * bytes_per_pixel + 1) = 0;*(pimagedata + pit * i + j * bytes_per_pixel + 2) = 0;}else{*(pimagedata + pit * i + j * bytes_per_pixel) = 255;*(pimagedata + pit * i + j * bytes_per_pixel + 1) = 255;*(pimagedata + pit * i + j * bytes_per_pixel + 2) = 255;}}}
}

灰度处理:
算法来源:C++MFC打开图片、彩图,以及对图像进行简单算法处理

void CGDITESTDlg::ImageGreyProcess(CImage& image)
{BYTE* pimagedata = (BYTE*)image.GetBits();	//获取到图片内存点的位置int width = image.GetWidth();int height = image.GetHeight();int pit = image.GetPitch();//图像每行字节数int bytes_per_pixel = image.GetBPP() / 8; //获取每像素的位数除以8得到每个像素占的字节数for (int i = 0; i < height; i++){for (int j = 0; j < width; j++){*(pimagedata + pit * i + j * bytes_per_pixel) *= 0.114;*(pimagedata + pit * i + j * bytes_per_pixel + 1) *= 0.587;*(pimagedata + pit * i + j * bytes_per_pixel + 2) *= 0.299;}}}

双击左侧控件的响应:
在这里插入图片描述

void CGDITESTDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{if (!isLoadedImage) //如果没有加载图片,则不会执行后续代码return;//未使用,仅测试CPoint ptCursor;GetCursorPos(&ptCursor);//获取执行此函数时的鼠标位置,屏幕坐标ClientToScreen(&point); //point是双击时的鼠标位置,坐标系是窗口客户区,所以要转换成屏幕坐标//未使用,仅测试CPoint ptCursor1(GetCurrentMessage()->pt); //双击时的鼠标位置,屏幕坐标GetDlgItem(IDC_PIC_ORIGIN)->GetWindowRect(&rc_origin);//控件的rect,屏幕坐标if (rc_origin.PtInRect(point))//如果右键在picture control区域抬起则放大显示灰度图片{CRect rect_ctl;m_ctl_pic_dsp.GetClientRect(&rect_ctl);float rectw = rect_ctl.Width();float recth = rect_ctl.Height();float rect_t = rectw / recth;if (rect_t < img_t){rect_ctl = CRect(rect_ctl.TopLeft(), CSize(rect_ctl.Width(), rect_ctl.Width() / img_t));}else{rect_ctl = CRect(rect_ctl.TopLeft(), CSize(rect_ctl.Height() * img_t, rect_ctl.Height()));}CDC* pdc = m_ctl_pic_dsp.GetDC();m_ctl_pic_dsp.SetBitmap(NULL);image_origin.Draw(pdc->m_hDC, rect_ctl);m_ctl_pic_dsp.ReleaseDC(pdc);return;}GetDlgItem(IDC_PIC_PROCESS)->GetWindowRect(&rc_binarization);if (rc_binarization.PtInRect(point))//如果右键在picture control区域抬起则放大显示灰度图片{CRect rect_ctl;m_ctl_pic_dsp.GetClientRect(&rect_ctl);float rectw = rect_ctl.Width();float recth = rect_ctl.Height();float rect_t = rectw / recth;if (rect_t < img_t){rect_ctl = CRect(rect_ctl.TopLeft(), CSize(rect_ctl.Width(), rect_ctl.Width() / img_t));}else{rect_ctl = CRect(rect_ctl.TopLeft(), CSize(rect_ctl.Height() * img_t, rect_ctl.Height()));}CDC* pdc = m_ctl_pic_dsp.GetDC();m_ctl_pic_dsp.SetBitmap(NULL);image_binarization.Draw(pdc->m_hDC, rect_ctl);m_ctl_pic_dsp.ReleaseDC(pdc);return;}GetDlgItem(IDC_PIC_PROCESS2)->GetWindowRect(&rc_grey);if (rc_grey.PtInRect(point))//如果右键在picture control区域抬起则放大显示灰度图片{CRect rect_ctl;m_ctl_pic_dsp.GetClientRect(&rect_ctl);float rectw = rect_ctl.Width();float recth = rect_ctl.Height();float rect_t = rectw / recth;if (rect_t < img_t){rect_ctl = CRect(rect_ctl.TopLeft(), CSize(rect_ctl.Width(), rect_ctl.Width() / img_t));}else{rect_ctl = CRect(rect_ctl.TopLeft(), CSize(rect_ctl.Height() * img_t, rect_ctl.Height()));}CDC* pdc = m_ctl_pic_dsp.GetDC();m_ctl_pic_dsp.SetBitmap(NULL);image_grey.Draw(pdc->m_hDC, rect_ctl);m_ctl_pic_dsp.ReleaseDC(pdc);return;}CDialogEx::OnLButtonDblClk(nFlags, point);
}

以上是通过窗口的双击时间回调函数,判断双击时鼠标的坐标,是否在控件的坐标Rect中,如果是,则执行对应代码。

也可以把双击的空间的notify属性设置为true,然后再时间中设置双击消息回调函数。
在这里插入图片描述
在这里插入图片描述

完整代码

MFC简单的图片处理工程-Gitee

参考

C++MFC打开图片、彩图,以及对图像进行简单算法处理

这篇关于[图像处理] MFC载入图片并进行二值化处理和灰度处理及其效果显示的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Python调用Orator ORM进行数据库操作

《Python调用OratorORM进行数据库操作》OratorORM是一个功能丰富且灵活的PythonORM库,旨在简化数据库操作,它支持多种数据库并提供了简洁且直观的API,下面我们就... 目录Orator ORM 主要特点安装使用示例总结Orator ORM 是一个功能丰富且灵活的 python O

Nginx设置连接超时并进行测试的方法步骤

《Nginx设置连接超时并进行测试的方法步骤》在高并发场景下,如果客户端与服务器的连接长时间未响应,会占用大量的系统资源,影响其他正常请求的处理效率,为了解决这个问题,可以通过设置Nginx的连接... 目录设置连接超时目的操作步骤测试连接超时测试方法:总结:设置连接超时目的设置客户端与服务器之间的连接

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

SpringBoot中使用 ThreadLocal 进行多线程上下文管理及注意事项小结

《SpringBoot中使用ThreadLocal进行多线程上下文管理及注意事项小结》本文详细介绍了ThreadLocal的原理、使用场景和示例代码,并在SpringBoot中使用ThreadLo... 目录前言技术积累1.什么是 ThreadLocal2. ThreadLocal 的原理2.1 线程隔离2

Python利用PIL进行图片压缩

《Python利用PIL进行图片压缩》有时在发送一些文件如PPT、Word时,由于文件中的图片太大,导致文件也太大,无法发送,所以本文为大家介绍了Python中图片压缩的方法,需要的可以参考下... 有时在发送一些文件如PPT、Word时,由于文件中的图片太大,导致文件也太大,无法发送,所有可以对文件中的图

java获取图片的大小、宽度、高度方式

《java获取图片的大小、宽度、高度方式》文章介绍了如何将File对象转换为MultipartFile对象的过程,并分享了个人经验,希望能为读者提供参考... 目China编程录Java获取图片的大小、宽度、高度File对象(该对象里面是图片)MultipartFile对象(该对象里面是图片)总结java获取图片

如何使用Spring boot的@Transactional进行事务管理

《如何使用Springboot的@Transactional进行事务管理》这篇文章介绍了SpringBoot中使用@Transactional注解进行声明式事务管理的详细信息,包括基本用法、核心配置... 目录一、前置条件二、基本用法1. 在方法上添加注解2. 在类上添加注解三、核心配置参数1. 传播行为(

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解