热门标签 | 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


推荐阅读
  • 本文详细介绍了如何在Ubuntu系统中下载适用于Intel处理器的64位版本,涵盖了不同Linux发行版对64位架构的不同命名方式,并提供了具体的下载链接和步骤。 ... [详细]
  • 作为一名程序员,从大学步入职场后,常常感受到一种难以言喻的空虚感。这种感觉或许源于对生活的不满、职业发展的瓶颈,或是日常琐事带来的压力。本文将深入探讨这种复杂的情感,并尝试寻找解决之道。 ... [详细]
  • 本文介绍如何在Linux服务器之间使用SCP命令进行文件传输。SCP(Secure Copy Protocol)是一种基于SSH的安全文件传输协议,支持从远程机器复制文件到本地服务器或反之。示例包括从192.168.45.147复制tomcat目录到本地/home路径。 ... [详细]
  • 通过与阿里云的合作,牛客网成功解决了跨国视频面试中的网络卡顿问题,为求职者和面试官提供了更加流畅的沟通体验。 ... [详细]
  • 深入解析:阿里实战 SpringCloud 微服务架构与应用
    本文将详细介绍 SpringCloud 在微服务架构中的应用,涵盖入门、实战和案例分析。通过丰富的代码示例和实际项目经验,帮助读者全面掌握 SpringCloud 的核心技术和最佳实践。 ... [详细]
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
  • 本文详细介绍了 MySQL 中 LAST_INSERT_ID() 函数的使用方法及其工作原理,包括如何获取最后一个插入记录的自增 ID、多行插入时的行为以及在不同客户端环境下的表现。 ... [详细]
  • 离散型随机变量的典型分布:超几何、几何、二项及泊松分布
    本文探讨了几种常见的离散型随机变量分布,包括超几何分布、几何分布、二项分布及其衍生的负二项分布和泊松分布。通过具体的模型和推导过程,详细介绍了这些分布的概率质量函数、期望和方差等关键特征。 ... [详细]
  • 技术人员转型项目管理:常见思维误区与挑战解析
    本文探讨了技术人员在向项目管理角色转变过程中常见的思维误区和困惑,分析了如何有效管理项目中的事务和人员,提供了实用的解决方案。 ... [详细]
  • 对于零基础的学习者来说,选择正确的学习路径至关重要。本文将详细介绍适合初学者的Python学习资源和方法,帮助新手找到适合自己的学习方式,顺利入门并逐步掌握编程技能。 ... [详细]
  • Python实现照片磨皮效果
    本文介绍如何使用Python和OpenCV库来实现照片的磨皮效果,使图片更加平滑并提升整体美感。 ... [详细]
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • MySQL索引详解与优化
    本文深入探讨了MySQL中的索引机制,包括索引的基本概念、优势与劣势、分类及其实现原理,并详细介绍了索引的使用场景和优化技巧。通过具体示例,帮助读者更好地理解和应用索引以提升数据库性能。 ... [详细]
  • 本文详细介绍了如何使用jQuery防止事件冒泡,确保子元素的点击事件不会触发父元素或祖先元素的相应事件。通过具体的代码示例和解释,帮助开发者更好地理解和应用这一技术。 ... [详细]
  • PHP中去除换行符的多种方法及应用场景
    本文将详细介绍在PHP中去除换行符的各种方法,并结合实际应用场景进行说明。通过本文,您将了解如何根据不同操作系统的特点,选择最合适的换行符处理方式。 ... [详细]
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社区 版权所有