1.软件界面:

本程序是基于MFC的单文档(SDI)程序,每次可以打开耽搁图片文件,可以保存,另存为图片文件。支持打开jpg,png,ico,bmp,jpeg等格式的图片。图片打开后的界面如下:

2.图片缩放:

通过滚动鼠标滚轮,可以调节图像的大小。默认是向上滚动鼠标滚轮为放大图片,向下滚动鼠标滚轮为缩小图片。当图片放大或者缩小到一定程度后在滑动鼠标滚轮会没有任何变化,因为图片过大的话会造成内存溢出,也就是不可能无限制的放大。下面是放大和缩小后的图片截图:

3.彩色图片灰度化

点击图像处理菜单按钮,会出现下拉菜单->灰度化,->二值化。其中点击灰度化按钮可以对打开的彩色图像进行灰度化(如果打开的是灰度图像或者二值化后的图像,则不处理) 。下图是点击“灰度化“选项之后的截图:

也可以对灰度化后的图像进行缩放、保存或者另存为。

4.OTSU二值化

本程序利用OTSU算法对图像进行二值化,点击“图像处理”菜单下的“二值化”选项,可以对打开的彩色(或灰度)图像二值化。其中二值化阈值设置对话框如下:

可以手动调整阈值,也可以直接利用OTSU算法计算出的阈值。比如本次打开的图像的OSTU算法计算出的最佳阈值是98,一般阈值在0-255之间。点击“确定”按钮,程序会自动调用手动调整的阈值,点击“取消”按钮,程序会自动用最佳阈值处理图像。

最佳阈值(本次打开的图像时98)处理的结果截图:

手动设置阈值150(也可以是其他值)后的结果:

技术要点部分:

1.打开图像

首先,通过MFC向导生成SDI程序模板,如下图:

在CImageProcessDoc.cpp中添加打开图像的部分代码,如下:

BOOLCImageProcessDoc::OnOpenDocument(LPCTSTR lpszPathName)
{if(!CDocument::OnOpenDocument(lpszPathName))return FALSE;// TODO: Add your specialized creation codeherem_image.Load(lpszPathName);return TRUE;
}

保存图像的代码如下:

BOOLCImageProcessDoc::OnSaveDocument(LPCTSTR lpszPathName)
{// TODO: Add your specialized code hereand/or call the base classm_image.Save(lpszPathName);return true;
}

2.图像的缩放

图像的缩放其实是吐过控制视图显示的比例来进项缩放的,首先利用应用程序向导添加鼠标滚轮的消息响应事件:

BOOL CImageProcessView::OnMouseWheel(UINTnFlags, short zDelta, CPoint pt)
{
//TODO: Add your message handler code here and/or call defaultif(zDelta> 0) //鼠标向上滚轮,放大图像
{if((scale+ 0.05)<4)scale+= 0.05;//每次增加0.05倍
}elseif(zDelta<0)//鼠标向下滚轮,缩小图像
{if((scale- 0.05)>0)scale -= 0.05;//每次减少0.05倍
}else{returnCView::OnMouseWheel(nFlags, zDelta, pt);
}Invalidate();returnCView::OnMouseWheel(nFlags, zDelta, pt);
}
3.图像的二值化
图像的二值化主要是用到了opencv里面的cvCvtColor函数,可以很方便的对彩色图像进行二值化,需要在CImageProcessDoc类中利用应用程序向导添加如下函数:
voidCImageProcessDoc::OnImageprocessingGray()
{// TODO: Add your command handler code hereIplImage* img;img=m_image.GetImage();IplImage* imgray =cvCreateImage(cvGetSize(img), 8, 1);cvCvtColor(img, imgray, CV_RGB2GRAY); //彩色图像灰度化m_image.CopyOf(imgray, 1);UpdateAllViews(NULL);
}

4.图像的二值化

OTSU算法原理:1. OTSU算法原理简介

对于一幅图像,设当前景与背景的分割阈值为t时,前景点占图像比例为w0,均值为u0,背景点占图像比例为w1,均值为u1。则整个图像的均值为u = w0*u0+w1*u1。建立目标函数g(t)=w0*(u0-u)^2+w1*(u1-u)^2,g(t)就是当分割阈值为t时的类间方差表达式。OTSU算法使得g(t)取得全局最大值,当g(t)为最大时所对应的t称为最佳阈值。OTSU算法又称为最大类间方差法。

实现二值化需要在CImageProcessDoc中添加以下两个功能函数(OtsuThreshold(IplImage *image)

和OnImageprocessingThreshold()):

intCImageProcessDoc::OtsuThreshold(IplImage *image)
{assert(NULL != image);int width = image->width;int height = image->height;int x=0,y=0;int pixelCount[256];float pixelPro[256];int i, j, pixelSum = width * height,threshold = 0;uchar* data = (uchar*)image->imageData;//初始化for(i = 0; i < 256; i++){pixelCount[i] = 0;pixelPro[i] = 0;}//统计灰度级中每个像素在整幅图像中的个数for(i = y; i < height; i++){for(j = x;j <width;j++){pixelCount[data[i *image->widthStep + j]]++;}}//计算每个像素在整幅图像中的比例for(i = 0; i < 256; i++){pixelPro[i] = (float)(pixelCount[i]) /(float)(pixelSum);}//经典ostu算法,得到前景和背景的分割//遍历灰度级[0,255],计算出方差最大的灰度值,为最佳阈值float w0, w1, u0tmp, u1tmp, u0, u1,u,deltaTmp, deltaMax = 0;for(i = 0; i < 256; i++){w0 = w1 = u0tmp = u1tmp = u0 = u1 = u =deltaTmp = 0;for(j = 0; j < 256; j++){if(j <= i) //背景部分{//以i为阈值分类,第一类总的概率w0 += pixelPro[j];      u0tmp += j * pixelPro[j];}else       //前景部分{//以i为阈值分类,第二类总的概率w1 += pixelPro[j];      u1tmp += j * pixelPro[j];}}u0 = u0tmp / w0;     //第一类的平均灰度u1 = u1tmp / w1;     //第二类的平均灰度u = u0tmp + u1tmp;       //整幅图像的平均灰度//计算类间方差deltaTmp = w0 * (u0 - u)*(u0 - u) + w1 *(u1 - u)*(u1 - u);//找出最大类间方差以及对应的阈值if(deltaTmp > deltaMax){  deltaMax = deltaTmp;threshold = i;}}//返回最佳阈值;return threshold;
}
//-----------------------------------------------------------------------
voidCImageProcessDoc::OnImageprocessingThreshold()
{// TODO: Add your command handler code hereIplImage* img;img=m_image.GetImage();//由CImage类 返回一个IplImage* 指针,因为:IplImage*GetImage() { return m_img; };IplImage* imgray =cvCreateImage(cvGetSize(img), 8, 1);cvCvtColor(img, imgray, CV_RGB2GRAY);IplImage* biImage =cvCreateImage(cvGetSize(imgray),8,1);//计算最佳阈值threshold = OtsuThreshold(imgray);AdjustThresholdDlg at;at.DoModal();//对图像二值化cvThreshold(imgray,biImage,threshold,255,CV_THRESH_BINARY);m_image.CopyOf(biImage, 1);UpdateAllViews(NULL);}

PS:

Opencv1.0在VS2010中的配置:

参考如下网址:http://www.cnblogs.com/etsang/p/3165184.html。

基于MFC和OpenCV的图像处理小软件相关推荐

  1. windows平台下基于QT和OpenCV搭建图像处理平台

        在之前的博客中,已经分别比较详细地阐述了"windows平台下基于VS和OpenCV"以及"Linux平台下基于QT和OpenCV"搭建图像处理框架,并 ...

  2. [Qt]图像处理小软件——给证件照换背景

    之前看到码农大佬分享的文章,感觉是个小乐子,就自己动手做了个小软件,方便还没学会PS的小伙伴们临时换背景Hhhh~ 资源索引: 这里是具体的步骤实现[VS2017]图像处理--给证件照换背景 这里是证 ...

  3. 基于MFC实现电脑录屏小程序

    1.新建一个"MFC应用"项目 2.项目名称自己选择 3.选择"基于对话框" 4.选择"资源视图"整体布局就是这样. 就改动了两个文件夹&q ...

  4. 基于MFC和OpenCV的摄像机定标与立体匹配测试程序

    最近整理了一下这两年一直在用的摄像机定标与立体匹配测试程序,将代码进行了重构,界面也做了调整,分享出来方便有需要的朋友使用.当然我的编程能力有限,程序可能还有各种bug,请大家多多包涵.相关问题欢迎留 ...

  5. 数字图像处理之matlab大作业:自制图像处理小工具

    学习的过程向来不是容易的,创造一个作品的过程更是不容易的.因此,在文章的最后,提供了两个现成的示例代码,大家直接可以拿来运行.在完成大作业的时候,大家可以在已有作品的基础上,按照自己的需求进行修改,添 ...

  6. 基于MFC简单图片裁剪工具

    话说这几天又没干啥正事,看书没效率,游戏也没怎么玩,尼玛时间都去哪儿了! --------------------------------------------------------------- ...

  7. 基于Android和OpenCV的答题卡识别软件

    基于Android和OpenCV的答题卡识别软件 1. 软件介绍 设计目标是可以添加不同的考试,在不同考试下可以设置模板,包括题目数量.答题卡样式.每题分值以及每题答案:扫描结果按列表显示,并讲识别出 ...

  8. OpenCV数字图像处理基于C++:灰度变换

    OpenCV数字图像处理基于C++:灰度变换 1.1 灰度变换概念 在图像预处理中,图像的灰度变换是图像增强的重要手段,灰度变换可以使图像对比度扩展,图像清晰,特征明显,灰度变换主要利用点运算来修正像 ...

  9. C++ MFC实现基于RFID读写器的上位机软件

    C++ MFC实现基于RFID读写器的上位机软件 该博客涉及的完整工程托管在https://github.com/Wsine/UpperMonitor,觉得好请给个Star (/▽\=) 运行和测试环 ...

最新文章

  1. Linux忘记密码常用的几种解决方法
  2. Spring应用的单元测试
  3. [HNOI2015]亚瑟王
  4. STM32 进阶教程 5 - 内联函数
  5. Linux deepin下普通用户免密切换至root用户
  6. 后台nodejs程序如何主动推送数据给浏览器
  7. Mybatis select元素返回List
  8. 08年冬季足协代表VS三水喜健友谊赛
  9. php 检查路劲是否存在,php 检查文件或目录是否存在代码总结
  10. python 嵌入 php,Python与PHP实现插入排序实例
  11. 【干货】数字经济时代的新思考:企业如何进行数字化转型及如何称为数据驱动型企业?...
  12. kettle连接GBASE数据库
  13. 滚动条插件better-scroll(BScroll)的使用
  14. matlab神经网络训练图解释,matlab实现神经网络算法
  15. ERD Online 4.0.0 免费私有部署方案
  16. 自然码官方辅助码键位图
  17. 蓝牙鼠标windows linux,windows linux双系统共用蓝牙鼠标
  18. 记一次git pull报错问题 is owned by: ‘xxx‘ but the current user is ‘xxx‘
  19. Docker——安装和启动
  20. Hexo+NexT 如何取消下划线

热门文章

  1. 情景软工编程题(待更新)
  2. 高阶ts内置泛型帮助类型
  3. Unity URP DOTS Animator
  4. 苹果抛弃 OpenGL !
  5. Linux SPI驱动学习——调用SPI读写函数
  6. 媒资系统服务器,服务器软件的配置-媒资系统安装说明.ppt
  7. erp系统 服务器在哪里的,云erp服务器在哪
  8. 韩顺平 uml视频教程 笔记
  9. webpack的基本使用03
  10. r5处理器_联想拯救者r7000 r7与r5哪个更值得买?差距大吗?下面价格和配置对比评测看完就明白了...