在之前的博客中我们已经实现读取用户选定的目录。并将其路径保存在对应的变量中。在这篇博文中我们将介绍怎样借助CvvImage类将图片显示在picture控件中,并自己主动读取目录下的其它图片。

  一、加入“下一张”button

  因为我们须要读取目录下的全部图像文件,而非某一张文件,因此有必要加入一个button来进行控制,具体功能就是:每单击一次这个button,程序就会自己主动读取下一张图片并显示在界面上。

因为之前已经具体介绍了MFC中加入Button控件的方式。这里不再赘述。加入一个button。命名为“下一张”。将ID更改为IDC_BUTTON_NextImage:

  二、编写遍历函数

  在上一篇博客中我们提到。在选中目录之后,程序会将目录的路径保存在m_Path变量之中。接下来我们就借助这个变量来进一步遍历其路径下的图像文件。这里我们专门编写一个函数来实现“遍历下一张图片”的功能,命名为GetNextBigImg。因此,须要向CGenderRecognitionMFCDlg类中加入这个成员函数。在类视图中右击对应的类,在快捷菜单中选择“加入->加入函数”,输入函数的属性:

  GetNextBigImg()函数主要承担着一下几个任务:

  1、開始遍历

  这里将GetNextBigImg()放在OnBnClickedButtonImagefile()函数中的末尾部分进行调用,用以在单击“图片目录”button读取目录信息之后启用文件读取程序。

  2、从当前目录路径下读入一个文件

  这里读取文件主要通过readdir函数来完毕,考虑到用户可能会选择一个空目录,因此这里须要对读取操作进行一次推断:

  1. if (m_pDir && (m_pEnt = readdir(m_pDir)) != NULL)
  2. {
  3.  
  4. }

  readdir()函数能够实现对当前目录结构(m_pDir)中的文件的无反复顺序读取。即每次读取完毕后都会自己主动移到下一个待读取的文件,与指针的机制相似,readdir()函数包括在dirent.h头文件里。之前已经加入并包括完毕。此时,m_pEnt变量中保存了文件名称称:

  3、推断是否为图像文件

  这里採用strstr()函数来推断文件名称中是否包括对应的扩展名字符串。这里默认的图像格式有四种:jpg 。bmp,png:

  1. if (m_pDir && (m_pEnt = readdir(m_pDir)) != NULL)
  2. {
  3. /**********推断是否为图像文件**********/
  4. char* jpg = strstr(m_pEnt->d_name,".jpg");
  5. char* bmp = strstr(m_pEnt->d_name,".bmp");
  6. char* png = strstr(m_pEnt->d_name,".png");
  7. }

  至于“m_pEnt->d_name”这样的调用格式。在dirent.h头文件里有着明白定义。有疑问的话能够查阅相关文件。接下里通过推断jpg、bmp、png这几个变量是否为空来确定文件是否是图像文件:

  1. if (m_pDir && (m_pEnt = readdir(m_pDir)) != NULL)
  2. {
  3. /**********推断是否为图像文件**********/
  4. char* jpg = strstr(m_pEnt->d_name,".jpg");
  5. char* bmp = strstr(m_pEnt->d_name,".bmp");
  6. char* png = strstr(m_pEnt->d_name,".png");
  7.  
  8. if (jpg == NULL && bmp == NULL && png == NULL) //假设该文件不是图像文件
  9. {
  10. GetNextBigImg();
  11. }
  12. else
  13. {
  14. /**********显示该图片**********/
  15. }
  16. }

  注意这里採用了一种递归的方式来实现非图像文件的轮询,即当前文件被判定为非图像文件时(jpg、bmp、png均为空),则调用自身GetNextBigImg(),也就意味着再次运行一遍readdir()函数。使得文件指针后移意味,层层递归实现终于的文件遍历。对应的。假设当前文件为三种图像文件里的一种,则将当前图片绘制到picture控件中,接下来编写绘制图像的代码。

  4、绘制图像至picture控件

  此时该轮到CvvImage大显身手了。在此之前。我们须要先为picture控件关联一个CRect类型的矩形变量。这个变量将用来保存picture控件在客户区所处的位置。

首先。为CGenderRecognitionMFCDlg类加入成员变量m_PicCtlRect:

  然后,再加入一个HDC(句柄)变量m_pPicCtlHdc。用于保存控件的句柄:

  然后在CGenderRecognitionMFCDlg的对话框初始化函数OnInitDialog()中编写两行代码,将控件、句柄、位置信息这三个变量相互关联起来:

  1. /*********初始化picture控件**********/
  2. m_pPicCtlHdc = GetDlgItem(IDC_PICTURE)->GetDC()->GetSafeHdc(); //返回控件句柄
  3. GetDlgItem(IDC_PICTURE)->GetClientRect(m_PicCtlRect); //关联控件位置

  将这两句代码加入到OnInitDialog()末尾就可以,这里有三个问题须要强调:

  (1)为什么须要用到句柄和CRect变量?原因非常easy。CvvImage类的要求。这里我们介绍一个查看函数形參的小技巧,即在函数名的括号里输入一个逗号,VS就会自己主动给出函数的形參格式:

  可见,DrawToHDC这个函数须要两个參数,一个是HDC类型的,一个是RECT*类型的。

  (2)怎样高速查找类的成员函数?最直接的方法就是通过类视图,单击对应的类来进行浏览就可以:

  当然,通过上方的搜索栏也是能够的。

  (3)OnInitDialog函数。这个函数在程序開始构造MFC框架时运行。因此有关控件的初始化操作都应该在这个函数中进行,而非构造函数。

  此时准备工作已经完毕,能够为GetNextBigImg()函数加入正式的显示代码了:

  1. /**********显示该图片**********/
  2. IplImage* imageSrc;
  3. CvvImage imageSrcCvvImg;
  4. char imageFullName [500]; //保存图像文件的全路径
  5.  
  6. sprintf_s(imageFullName,"%s%s",m_ImageDir,m_pEnt->d_name); //拼出文件全路径
  7. imageSrc = cvLoadImage(imageFullName);
  8. imageSrcCvvImg.CopyOf(imageSrc);
  9. imageSrcCvvImg.DrawToHDC(m_pPicCtlHdc,m_PicCtlRect);
  10. cvReleaseImage(&imageSrc);

  此时。运行程序,通过“图像目录button”。选择一个含有图片文件的目录,程序正常显示图片:

  5、加入“下一张”功能

  接下来我们为界面中的“下一张”button指定其功能。双击“下一张”button,加入响应函数:

  因为之前我们已经将图片轮询、显示操作封装在了GetNextBigImg()函数中,在这里我们仅仅需调用一把这个函数就可以实现“下一张”的功能:

  1. void CGenderRecognitionMFCDlg::OnBnClickedButtonNextimage()
  2. {
  3. GetNextBigImg();
  4. // TODO: 在此加入控件通知处理程序代码
  5. }

  OK,大功告成。

  三、总结

  经过这篇博文,我们的MFC框架已经具备了主要的图像显示功能,在下一篇博文中我们将向当中加入人脸检測的功能。

这里有几个问题须要注意。

  1、OpenCv2.x关于图片显示的问题

  大家留心观察会发现,这里用到的CvvImage方法是全然基于OpenCv1.x的,用IplImage变量来表示图片。

  2、递归层数的问题

  这里GetNextBigImg()函数存在一个递归调用的过程,存在递归就须要考虑递归深度的问题。这里每遍历到一个非图像文件,递归的深度就添加一层,假设超过规定的递归深度,程序就会崩溃,从这个角度来讲通过递归的方法来轮询图像文件和非图像文件,是存在严重BUG隐患的,仅仅要目录下有足够多的非图像文件。程序必定会因为无限递归而崩溃。相信大家有能力找到其它更安全的方法来解决问题。

C++开发人脸性别识别教程(9)——搭建MFC框架之显示图片的更多相关文章

  1. C++开发人脸性别识别教程(12)——加入性别识别功能

    经过之前几篇博客的解说,我们已经成功搭建了MFC应用框架,并实现了主要的图像显示和人脸检測程序,在这篇博文中我们要向当中加入性别识别代码. 关于性别识别,之前已经专门拿出两篇博客的篇幅来进行解说.这里 ...

  2. C++开发人脸性别识别教程(19)——界面美化

    在这篇博文中将完毕<C++开发人脸性别识别>的收尾工作.主要内容分为两部分:加入视频暂定功能.界面规范化. 一 视频暂停功能 严格来说这个视频暂定功能算是视频人脸性别识别的一个遗留问题,本 ...

  3. C++开发人脸性别识别教程(10)——加入图片的人脸检測程序

    现在我们的MFC框架已经初具规模,能够读取并显示目录下的图片.在这篇博文中我们将向当中加入人脸检測的程序. 一.人脸检測算法 这里我们使用OpenCv封装的Adaboost方法来进行人脸检測,參见:C ...

  4. C++开发人脸性别识别教程(3)——OpenCv配置和ImageWatch插件介绍

    OpenCv是C++图像处理的重要工具.这个人脸性别识别的项目就是借助OpenCv进行开发的. 尽管网上已经有了非常多关于OpenCv的配置教程,但出于教程完整性考虑.这里还是用专门的一篇博客来介绍O ...

  5. C++开发人脸性别识别教程(16)——视频人脸性别识别

    在之前的博文中我们已经可以顺利驱动摄像头来採集源图像.在这篇博文中将正式为其加入性别识别的代码,实现摄像头视频的人脸性别识别. 一.人脸检測 在得到摄像头採集的源图像之后,首先要做的就是对其进行人脸检 ...

  6. C++开发人脸性别识别教程(7)——搭建MFC框架之界面绘制

    在之前的博客中我们已经将项目中用到的算法表述完成,包含人脸检測算法以及四种性别识别算法,在这篇博客中我们将着手搭建主要的MFC框架. 一.框架概况 在这篇博文中我们将搭建最主要的MFC框架.绘制MFC ...

  7. C++开发人脸性别识别教程(5)——通过FaceRecognizer类实现性别识别

    在之前的博客中已经攻克了人脸检測的问题,我们计划在这篇博客中介绍人脸识别.性别识别方面的相关实现方法. 事实上性别识别和人脸识别本质上是相似的,由于这里仅仅是一个简单的MFC开发,主要工作并不在算法研 ...

  8. C++开发人脸性别识别教程(8)——搭建MFC框架之读取目录信息

    在上一篇博客中我们已经绘制了MFC界面,在这篇博客中我们将加入响应代码,为MFC框架加入一个最主要的功能:打开一个目录. 一.加入相关头文件 这里头文件主要包括三类:opencv头文件.批量读取文件相 ...

  9. C++开发人脸性别识别教程(6)——通过SVM实现性别识别

    http://blog.csdn.net/u013088062/article/details/50480518

随机推荐

  1. python对XML 操作

    一.XML的读取. 在 NewEdit 中有代码片段的功能,代码片段分为片段的分类和片段的内容.在缺省情况下都是用XML格式保存的.下面我讲述一下,如何使用minidom来读取和保存XML文件. 下面 ...

  2. web.xml中load-on-startup

    <servlet> <servlet-name>SystemInit</servlet-name> <servlet-class>sjgl.system ...

  3. selenium3 + Python - 处理浏览器弹窗(转载)

    作者:Real_Tino 转载链接:https://blog.csdn.net/real_tino/article/details/59068827 我们在浏览网页时经常会碰到各种花样的弹窗,在做UI ...

  4. poj1958-汉诺四塔问题(三种方法)

    链接:http://poj.org/problem?id=1958 大意:汉诺塔升级版,四根柱子,n个盘子,求最少移动次数: 两种方法 递推or递归(当然还有思路3--打表) 思路1:递推(或者DP? ...

  5. C#之纯数字判断

    public bool isNaN(string temp) { ; i <temp.Length; i++) { byte tempByte = Convert.ToByte(temp[i]) ...

  6. ESB报文自动生成工具

    为了提高日常工作效率,自己在闲暇时间写了一款工具,功能界面如下图所示: 从ESB文档中复制报文字段.字段类型.报文字段注释,选择生成文件路径并输入文件名: 输入完毕后点击生成按钮,自动生成Contex ...

  7. mysql数据库之存储过程入门

    引用:百度百科 存储过程 存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存 ...

  8. windows下react-native搭建环境

    第一步:安装Java 1.下载JDK,选择适应自己的机型:官网地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downl ...

  9. 关于c# winform使用FidderCore.dll 遇到的一些问题,请求支援

    小弟最近再研究winform用fidder抓取包的过程.开始都很顺利,并且成功开启了代理网络.同时手机也设置代理,并且手机可以上网,而且电脑也能抓到手机的请求. 但是遇到两个问题. 1.,这里的关闭代 ...

  10. Java_Web之宠物管理系统

    使用JSP+servLet实现宠物管理系统,oraC1e11g作为后台数据厍,实现查看宠物和增加宠物的功能由你实现,如图: 其中宠物包栝:狗.猫.鸟.鼠 具体要求及推荐实现步骤 第一步:创建数据库代码 ...