OPENCV学习笔记15_算法设计中使用策略模式

  Building a bug-free(无BUG) application is just the beginning. What you really want is an application that you and the programmers working with you(团队) will be able to easily adapt and evolve (修改和升级)as new requirements come in(随着新的需求进入,面临新的需求).

  Basically(总体来说), a design pattern is a sound(可靠的), reusable solution (可重用)to a generic problem that occurs frequently in software designing. Many software patterns have been introduced and well documented. Good programmers should build a working knowledge of these existing patterns.

  The objective of(目的) the Strategy [?str?t?d?i] design pattern (策略设计模式)is to encapsulate (封装)an algorithm in(算法) a class.

  示例

  构建一个简单的算法,用来识别图像中具有某种颜色的所有像素。这个算法必须输入一个图像和一个颜色,并且返回一个二值图像,显示具有指定颜的像素。The tolerance(公差) with which we want to accept a color will be another parameter to be specified(规定,指定) before running the algorithm [??lg?r?e?m].

  一旦用策略设计模式把算法封装进类,就可以通过创建类的实例来部署算法,实例通常是在程序初始化的时候创建的。在运行构造函数时,类的实例会用默认值初始化算法的各种参数,以便它能立即进入可用状态。

  let‘s start with an example on how it can be deployed(部署) and used.

#include "colordetector.h"
#include <vector>

int ColorDetector::getDistanceToTargetColor(const Vec3b& color) const{
    return getColorDistance(color, target);
}

int ColorDetector::getColorDistance(const Vec3b& color1, const Vec3b& color2) const{
    return abs(color1[0] - color2[0]) + abs(color1[1] - color2[1]) + abs(color1[2] - color2[2]);
}

void ColorDetector::setColorDistanceThreshold(int distance){
    if (distance < 0)
    distance = 0;
    maxDist = distance;
}

int ColorDetector::getColorDistanceThreshold() const {
    return maxDist;
}

void  ColorDetector::setTargetColor(uchar blue, uchar green, uchar red) {
    target = Vec3b(blue, green, red);                //Vec3b color
}

void  ColorDetector::setTargetColor(Vec3b color) {
    target = color;
}

Vec3b ColorDetector::getTargetColor() const {
    return target;
}

Mat ColorDetector::process(const cv::Mat &image) {
      // re-allocate binary map if necessary same size as input image, but 1-channel
      result.create(image.size(),CV_8U);
      // get the iterators
      Mat_<cv::Vec3b>::const_iterator it= image.begin<Vec3b>();
      Mat_<cv::Vec3b>::const_iterator itend= image.end<Vec3b>();
      Mat_<uchar>::iterator itout= result.begin<uchar>();
      for ( ; it!= itend; ++it, ++itout)
      {
          // compute distance from target color
          if (getDistanceToTargetColor(*it) < maxDist) {
              *itout= 255;
          }
          else {
              *itout= 0;
          }
      }
      return result;
}

main.cpp

#if !defined COLORDETECT
#define COLORDETECT

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include<iostream>
using namespace std;
using namespace cv;

class ColorDetector {
  private:
      int maxDist;    // minimum acceptable distance
      Vec3b target;   // target color
      Mat result;     // image containing resulting binary map
  public:
      /*
      使用策略设计模式的原因之一,让算法的部署尽可能简单。
      最简单的构造函数是空函数。它会创建一个算法类的实例,并处于有效状态。
      然后我们在构造函数中初始化全部输入参数,设置为默认值。
      */
      // empty constructor    default parameter initialization here
      // ColorDetector():minDist(20){target[0]=target[1]=target[2]=0;}
      ColorDetector() : maxDist(255), target(0,0,0){}    //构造函数
      /*
      此时,创建该算法类的用户可以立即调用处理方法并传入一个有效的图像,然后得到一个有效的输出。
      这是策略模式的另一个目的,即保证只要参数正确,算法就能正常运行。可由多个构造函数.
      */

      // Computes the distance from target color.

      int getDistanceToTargetColor(const Vec3b& color) const;      //  no{ }
      /*
      Vec3b target;   // target color

      int ColorDetector::getDistanceToTargetColor(const Vec3b& color) const{
          return getColorDistance(color, target);
      }
      void  ColorDetector::setTargetColor(Vec3b color) {
          target = color;
      }
      */

      int getColorDistance(const Vec3b& color1, const Vec3b& color2) const;

      // Processes the image. Returns a 1-channel binary image.
      Mat process(const Mat &image);

      /*------用户显然希望使用个性化设置,可以用相应的设计方法和获取方法来实现这个功能。-----*/
      void setColorDistanceThreshold(int distance);
      // Gets the color distance threshold
      int getColorDistanceThreshold() const;

      /*
      提供了setTargetColor方法的两种定义。 第一个版本用三个参数表示三个颜色组件,第二个版本用cv::Vec3b保存颜色值。
      让算法类更便于使用,用户只需要选择最合适的设值函数。
      */
      // Sets the color to be detected
      void setTargetColor(uchar blue, uchar green, uchar red);
      // Sets the color to be detected
      void setTargetColor(Vec3b color);

      // Gets the color to be detected
      Vec3b getTargetColor() const;
};  // semicolons need

#endif

colordetector.h

#include "colordetector.h"
#include <vector>

int ColorDetector::getDistanceToTargetColor(const Vec3b& color) const{
    return getColorDistance(color, target);
}

int ColorDetector::getColorDistance(const Vec3b& color1, const Vec3b& color2) const{
    return abs(color1[0] - color2[0]) + abs(color1[1] - color2[1]) + abs(color1[2] - color2[2]);
}

void ColorDetector::setColorDistanceThreshold(int distance){
    if (distance < 0)
    distance = 0;
    maxDist = distance;
}

int ColorDetector::getColorDistanceThreshold() const {
    return maxDist;
}

void  ColorDetector::setTargetColor(uchar blue, uchar green, uchar red) {
    target = Vec3b(blue, green, red);                //Vec3b color
}

void  ColorDetector::setTargetColor(Vec3b color) {
    target = color;
}

Vec3b ColorDetector::getTargetColor() const {
    return target;
}

Mat ColorDetector::process(const cv::Mat &image) {
      // re-allocate binary map if necessary same size as input image, but 1-channel
      result.create(image.size(),CV_8U);
      // get the iterators
      Mat_<cv::Vec3b>::const_iterator it= image.begin<Vec3b>();
      Mat_<cv::Vec3b>::const_iterator itend= image.end<Vec3b>();
      Mat_<uchar>::iterator itout= result.begin<uchar>();
      for ( ; it!= itend; ++it, ++itout)
      {
          // compute distance from target color
          if (getDistanceToTargetColor(*it) < maxDist) {
              *itout= 255;
          }
          else {
              *itout= 0;
          }
      }
      return result;
}

colordetector.cpp

时间: 2024-10-05 22:52:05

OPENCV学习笔记15_算法设计中使用策略模式的相关文章

OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波

http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 2013-03-23 17:44 16963人阅读 评论(28) 收藏 举报 分类: 机器视觉(34) 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] KAZE系列笔记: OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 OpenCV学习笔记(28)KA

OpenCV学习笔记[3]Java Demo人脸识别

OpenCV学习笔记:Java Demo人脸识别 [简介] 我记得在很久以前,CSDN似乎搞过一个活动,给一个橘子林的照片,让程序计算相片里有多少个橘子.之所以对这个问题记忆犹新,是因为在专业学习初期,相比于排序遍历搜索等简单算法而言,"图像识别"算法一直是难以理解的东西,而我偏偏又痴迷于此,不管自己多么无知,对于令我迷惑的问题总是充满着解决的渴望. 通过对OpenCV的初步了解,我发现图像识别的很多问题都可以用它方便的解决,本次将是一个来自官方的人脸识别的实例,我们提供图像,使用内置

OpenCV 学习笔记(模板匹配)

OpenCV 学习笔记(模板匹配) 模板匹配是在一幅图像中寻找一个特定目标的方法之一.这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否"相似",当相似度足够高时,就认为找到了我们的目标. 在 OpenCV 中,提供了相应的函数完成这个操作. matchTemplate 函数:在模板和输入图像之间寻找匹配,获得匹配结果图像 minMaxLoc 函数:在给定的矩阵中寻找最大和最小值,并给出它们的位置 在具体介绍这两个函数之前呢,我们还要介绍一个概念,就是如何来评价两

大数据学习笔记6&#183;社会计算中的大数据(4)

上一篇介绍了LifeSpec项目,这个项目是关于用户理解和用户画像的.这篇是社会计算部分的最后一篇,关于用户连接和图隐私. 用户连接与隐私保护 用户连接与隐私保护有很强的相关性. 上图中,左边有两个网络.对于用户连接,我们的目标是映射这两个网络和连接这些网络中的用户节点.然后,我们就能产生一个更大的网络.这样,用户就能够被连接在一起,我们就可以知道跨网络的用户信息. 但是,如果从隐私的角度来看这个问题,把第一个图看成一个匿名化处理后的图,称其为目标图:把第二张图看成辅助图或者攻击者可获得的信息.

Opencv学习笔记(六)SURF学习笔记

原创文章,转载请注明出处:http://blog.csdn.net/crzy_sparrow/article/details/7392345 本人挺菜的,肯定有非常多错误纰漏之处 ,希望大家不吝指正. 看了harris角点检測之后,開始研究SURF角点检測,发现挺复杂的,一时也仅仅了解了大概,把了解的东西总结下,以便下次深入学习. SURF角点检測算法是对SIFT的一种改进,主要体如今速度上,效率更高.它和SIFT的主要差别是图像多尺度空间的构建方法不同. 在计算视觉领域,尺度空间被象征性的表述

opencv学习笔记(四)投影

opencv学习笔记(四)投影 任选了一张图片用于测试,图片如下所示: 1 #include <cv.h> 2 #include <highgui.h> 3 using namespace std; 4 using namespace cv; 5 int main() 6 { 7 IplImage * src = cvLoadImage("cat.png", 0); //强制转化读取图像为灰度图 8 cvShowImage("灰度图像", s

OpenCV学习笔记(01)我的第一个OpenCV程序(环境配置)

昨天刚刚考完编译原理,私心想着可以做一些与考试无关的东西了.一直想做和图像处理相关的东西,趁这段时间有空学习一下OpenCV,搭建环境真是一件麻烦的事情,搞了近三个小时终于OK了.先来张图: 大致描述一下步骤吧: 一.安装前准备 1.VS2012(网上看到很多用的VS2010,但是基本不影响) 2.OpenCV 安装包(我下载的是最新的2.4.9) 二.安装OpenCV 1.解压OPenCV 说是安装,其实就是解压,OpenCV的Windows安装程序就是一个自解压程序: 这里我解压到C:\Pr

算法学习笔记 KMP算法之 next 数组详解

最近回顾了下字符串匹配 KMP 算法,相对于朴素匹配算法,KMP算法核心改进就在于:待匹配串指针 i 不发生回溯,模式串指针 j 跳转到 next[j],即变为了 j = next[j]. 由此时间复杂度由朴素匹配的 O(m*n) 降到了 O(m+n), 其中模式串长度 m, 待匹配文本串长 n. 其中,比较难理解的地方就是 next 数组的求法.next 数组的含义:代表当前字符之前的字符串中,有多大长度的相同前缀后缀,也可看作有限状态自动机的状态,而且从自动机的角度反而更容易推导一些. "前

OpenCV学习笔记[5]FLANN特征匹配

OpenCV学习笔记:FLANN特征匹配 本次给出FLANN特征匹配的Java实现. [简介] 特征匹配记录下目标图像与待匹配图像的特征点(KeyPoint),并根据特征点集合构造特征量(descriptor),对这个特征量进行比较.筛选,最终得到一个匹配点的映射集合.我们也可以根据这个集合的大小来衡量两幅图片的匹配程度. 特征匹配与模板匹配不同,由于是计算特征点集合的相关度,转置操作对匹配影响不大,但它容易受到失真.缩放的影响. [特征匹配] FeatureMatching.java: imp