热门标签 | HotTags
当前位置:  开发笔记 > 程序员 > 正文

OpenCV—用控制器设计模式实现功能模块间的通信

OpenCV—用控制器设计模式实现功能模块间的通信《Opencv计算机视觉编程攻略(第二版)》书中例子只给出了部分关键代码,将实现例子的笔记整理出来做为学习笔记。本文是书中3.3节:用控

       

OpenCV—用控制器设计模式实现功能模块间的通信

OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,
_T("image file(*.bmp;*,jpg)|*.bmp;*.jpg|ALL Files(*.*)|*.*||"),NULL);

dlg.m_ofn.lpstrTitle=_T("Open Image");

//如果选中了一个文件名
if(dlg.DoModal()==IDOK)
{
//取得选定文件名的完整路径
//Cstring->std::string
CString cstrfilename = dlg.GetPathName();//.GetPathName返回的是CString类型的字符串
std::string filename;
setlocale(LC_ALL, "chs");
char *p = new char[256];
wcstombs( p, cstrfilename, 256 );
filename = p;

//设置并显示输入的图像,注意controller变量已经在前文向对话框类中添加过了
controller.setInputImage(filename); //.setInputImage方法输入的为std::string类型的字符串
cv::imshow("Input Image",controller.getInputImage());
}
}

这里要注意的是,书中使用.GetPathName()方法,返回的是CString类型的字符串表示的文件路径,而.setInputImage方法输入要求为std::string类型的字符串,因此需要转换。转化方法为网上下载,应该有更简单的方法。

打开图片的效果

(3)process按钮的处理程序

双击process按钮进入其处理程序代码位置。添加处理代码如下:

void CopencvColorDetectControllerDlg::OnBnClickedProcess()
{
// TODO: 在此添加控件通知处理程序代码
//这里颜色采用硬编码
//controller.setTargetColor(130,190,230);//源代码的目标颜色
controller.setTargetColor(140,174,209); //根据读入城堡图像调整了一下目标颜色

//处理输入图像并显示结果
controller.process();
cv::imshow("Output Result",controller.getLastResult());
}
注意,书上ColorDetectController类型的成员变量定义为colordetect,而本文中定义的控制器实例名称为controller(即控制器变量名称)(见3.3.4节(1)小节),因此,注意将书中的名称colordetect改为controller。通过process按钮的颜色检测结果

5.使用MVC架构为程序增加肤色检测功能

书中的扩展阅读介绍了MVC架构。MVC架构的目的是生成一个能把程序逻辑与用户接口清晰地隔离的程序。MVC主要包含三个组件:模型、视图、控制器。

模型存放与应用程序有关的信息。他控制着程序的所有数据,当产生新数据时,它会通知控制器,然后控制器通知视图显示新结果。

视图相当于用户接口。它由不同的窗口组成,窗口可以向用户展示数据并且允许用户与程序交互。视图的功能之一就是将用户发出的命令发送给控制器。当有新数据时,视图会刷新以显示新的信息。

控制器是连接视图和模型的模块。它从视图接收请求,并转发给模型中对应的方法。模型状态发生变化时会通知控制器,然后控制器通知视图进行刷新,以显示新信息。

下面我们将扩展阅读介绍的不同的色彩空间的知识,以及在HSV色彩空间中搜寻特定颜色物体的例子添加到MFC程序中,为程序增加一项检测肤色的功能。

注:在对特定物体做初步检测时,颜色信息非常有用。例如在辅助驾驶程序中检测路标,就要凭借标准路标的颜色快速地提取可能是路标的信息。另一个例子是检测皮肤的颜色,检测到的皮肤区域可作为图像中有人存在的标志。在手势识别中经常使用这个方法,用肤色检测来确定手的位置。

下面将书中的肤色检测的例子按照MVC模式,添加到刚才编写的MFC程序中。

(1)模型层:在算法类中定义肤色检测方法

为了给算法添加肤色检测功能,需要在ColorDetecor算法类中定义一个肤色检测方法。打开包含算法类的头文件colordetector.h,在类定义中添加如下肤色检测代码:

  //增加肤色检测方法 
void detectHScolor(const cv::Mat& image,// input image
double minHue, double maxHue,// Hue interval
double minSat, double maxSat, // saturation interval
cv::Mat& mask) {// output mask输出肤色掩码

// convert into HSV space
cv::Mat hsv;
cv::cvtColor(image, hsv, CV_BGR2HSV);

// split the 3 channels into 3 images
std::vector channels;
cv::split(hsv, channels);
// channels[0] is the Hue 色调
// channels[1] is the Saturation 饱和度
// channels[2] is the Value 亮度

// Hue masking
cv::Mat mask1; // under maxHue
cv::threshold(channels[0], mask1, maxHue, 255, cv::THRESH_BINARY_INV);
cv::Mat mask2; // over minHue
cv::threshold(channels[0], mask2, minHue, 255, cv::THRESH_BINARY);

cv::Mat hueMask; // hue mask
if (minHue hueMask = mask1 & mask2;
else // if interval crosses the zero-degree axis
hueMask = mask1 | mask2;

// Saturation masking
// under maxSat
cv::threshold(channels[1], mask1, maxSat, 255, cv::THRESH_BINARY_INV);
// over minSat
cv::threshold(channels[1], mask2, minSat, 255, cv::THRESH_BINARY);

cv::Mat satMask; // saturation mask
satMask = mask1 & mask2;

// combined mask组合掩码
mask = hueMask&satMask;
}

(2)视图层:在对话框中添加detect skin按钮

在对话框中使用工具添加按钮,增加一个处理按钮,并名称和ID分别改为detect skin和ID_DETECTSKIN。

添加肤色检测按钮

添加完按钮后,双击按钮进入响应函数编写,添加如下按钮响应代码:

void CopencvColorDetectControllerDlg::OnBnClickedDetectskin()
{
// TODO: 在此添加控件通知处理程序代码
controller.detectHScolor();//调用检测肤色的算法
cv::imshow("Output detected skin",controller.getLastResult());//调用获取检测结果的方法显示结果
}

上面的代码表示,视图层通过按钮来调用控制器层运行检测肤色的方法controller.detectHScolor(),按照上文在控制器中定义方法的命名规则,我们也将该方法命名为detectHScolor()。该方法的算法实现为算法类中添加的detectHScolor()方法,控制器只是将视图层的请求重新定向到算法类(即实现委托)。

(3)控制器层:在控制器类中定义肤色检测方法

如何将算法层与视图层连接起来呢?这就要通过控制器层,下面将介绍控制器层如何实现它在MVC架构中的作用。

控制器是连接视图和模型的模块。它从视图接收请求,并转发给模型中对应的方法。模型状态发生变化时会通知控制器,然后控制器通知视图进行刷新,以显示新信息。

这里我们在控制器类中添加检测肤色的方法供视图层调用,而实际的处理则是由控制器层通知模型层的算法来处理。

在控制器类ColorDetectController中定义肤色检测方法,代码如下:

 void detectHScolor() {

cv::Mat mask;
cdetect->detectHScolor(image,160,10,25,166,mask);//调用算法类中的肤色检测算法,返回mask
//显示掩码后的图像
image.copyTo(result,mask);
}

控制器类中的肤色检测方法detectHScolor将输入图像image传递给模型层的算法cdetect->detectHScolor(…),由算法检测肤色后返回检测结果掩码mask。接下来,控制器的detectHScolor方法再将mask应用到输入图像上image.copyTo(result,mask),生成只有肤色部分的图像result。这时,视图层调用方法controller.getLastResult()就可以从控制器层获得最终的肤色检测结果了。

打开一幅有人物的图像


显示肤色检测结果

肤色检测的参数设置在控制器层的controller.detectHScolor()方法中,下一步还可以将参数设置改到视图层作为用户与程序的交互功能。


转载请注明:iracer的CSDN博客 http://blog.csdn.net/iracer/article/details/48606751


推荐阅读
  • 使用Numpy实现无外部库依赖的双线性插值图像缩放
    本文介绍如何仅使用Numpy库,通过双线性插值方法实现图像的高效缩放,避免了对OpenCV等图像处理库的依赖。文中详细解释了算法原理,并提供了完整的代码示例。 ... [详细]
  • 深入理解父组件与子组件的引用和访问
    本文详细介绍了如何在Vue.js中通过$children和$refs属性实现父组件对子组件的访问,并提供了具体的代码示例及最佳实践。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Søren Kierkegaard famously stated that life can only be understood in retrospect but must be lived moving forward. This perspective delves into the intricate relationship between our lived experiences and our reflections on them. ... [详细]
  • PyCharm中配置Pylint静态代码分析工具
    本文详细介绍如何在PyCharm中配置和使用Pylint,帮助开发者进行静态代码检查,确保代码符合PEP8规范,提高代码质量。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 优化ASM字节码操作:简化类转换与移除冗余指令
    本文探讨如何利用ASM框架进行字节码操作,以优化现有类的转换过程,简化复杂的转换逻辑,并移除不必要的加0操作。通过这些技术手段,可以显著提升代码性能和可维护性。 ... [详细]
  • 本文总结了2018年的关键成就,包括职业变动、购车、考取驾照等重要事件,并分享了读书、工作、家庭和朋友方面的感悟。同时,展望2019年,制定了健康、软实力提升和技术学习的具体目标。 ... [详细]
  • 资源推荐 | TensorFlow官方中文教程助力英语非母语者学习
    来源:机器之心。本文详细介绍了TensorFlow官方提供的中文版教程和指南,帮助开发者更好地理解和应用这一强大的开源机器学习平台。 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • python的交互模式怎么输出名文汉字[python常见问题]
    在命令行模式下敲命令python,就看到类似如下的一堆文本输出,然后就进入到Python交互模式,它的提示符是>>>,此时我们可以使用print() ... [详细]
  • 本文详细介绍了如何使用PHP检测AJAX请求,通过分析预定义服务器变量来判断请求是否来自XMLHttpRequest。此方法简单实用,适用于各种Web开发场景。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
author-avatar
男人要走火_293
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有