[图像处理] 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

相关文章

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

Python自动化处理PDF文档的操作完整指南

《Python自动化处理PDF文档的操作完整指南》在办公自动化中,PDF文档处理是一项常见需求,本文将介绍如何使用Python实现PDF文档的自动化处理,感兴趣的小伙伴可以跟随小编一起学习一下... 目录使用pymupdf读写PDF文件基本概念安装pymupdf提取文本内容提取图像添加水印使用pdfplum