提取功能。在课堂上有很多getter / setter是正常的吗?

时间:2012-11-12 18:49:26

标签: c++ image-processing opencv getter-setter

我有一堆不同的Feature类来计算图像特征 我必须从这些类中提取“关键特征”,这些特征将被用作搜索关键字 我还将存储部分Feature类。我无法存储整个要素类,因为这样效率很低。

现在,我想到的是写一个Stored_features课程,将“关键特征”放在一起 我的布局是:

   Facial_features
   |      |       |
   |      V       |
   | .---Feature1 V   <|-- Abstract_feature
   | | .---Feature2   <|---'
   V V V
  Stored_features

我的问题是,这样的Stored_features课程会有很多getter和setter,据我所知, getter和setter表示设计不好。是否有一种易于维护的方法可以避免过多的吸气剂和制定者?

重点是我看到我的代码与此布局非常紧密地联系在一起:(

编辑:

我的代码按要求提取。

#include <opencv2/core/core.hpp>

class Abstract_feature{
public:
  virtual void calculate()=0;
  virtual void draw(cv::Mat& canvas)=0;
  /// to put values into Stored_features
  virtual void registrate_key_values(Stored_features&) const=0;
};

class Facial_features : Abstract_feature{
public:
  virtual void calculate()
  { 
    es.calculate; sc.calculate; 
    /*etc but iterating over a list of Abstract_feature's*/
  }
  Stored_features get_stored_features() const
  {
    return sf.clone();
  }
private:
  Stored_features sf;
  Head_size es;
  Skin_color sc;
};

class Head_size : public Abstract_feature{
  //you can guess the impl.
};    

class Stored_features{
public:
  typedef enum{SKIN_COLOR=0, HEAD_SIZE_WIDTH,HEAD_SIZE_HEIGHT} Name;
public:
  void set_key_feature(Name, double value);
  cv::Mat get_feature_vector() const {return key_values;}
private:
  cv::Mat key_values;
  // and here would come other features eg.
  cv::Rect head_roi; // I don't search based on these. (So I should not use getters/setters?)
};

添加了opencv,无论如何都是一个基于opencv的项目。

3 个答案:

答案 0 :(得分:2)

许多吸气剂和制定者本身并不表示糟糕的设计。但是,它们可以暗示您的类可以在较小的类中进行分解。以“客户”为例,如果您将所有名称,地址,交货地址字段放在一个类中,这将是一个糟糕的设计,您应该使用“地址”类进行拆分。

我不确定你的设计是什么,关键是如果你需要100个吸气剂,因为你有100个,不相关的领域使用100个吸气剂

答案 1 :(得分:1)

您可能应该对您的功能有所了解literal,而在抽象和数学术语方面则更多。您似乎将面部描述为面部特征的组合,每个面部特征使用一些程序计算,并且每个单独的面部特征因此将一个(或可能是几个)标量值贡献给单个特征向量。因此,我建议将您的功能存储为:向量。使用一些矢量类(std :: vector可能有效,但您可能会考虑使用线性数学库,原因我将在下面解释)。

如果您愿意,您仍然可以extract来自这些向量的标量面部特征。例如,如果您有N个功能,则可以将其保存在N维列功能向量x中。现在,您可以将任何线性提取运算符编写为行向量甚至矩阵A,并获得所需的功能ff = A*x。如果你想存储这些矩阵和向量,你可以更好地使用像Boost uBLAS这样的库。

现在,你仍然应该以某种方式表达你的搜索查询。您应该在向量中重写搜索查询,而不是使用getter和setter,您可以使用距离(Euclidean,Manhattan)来计算存储的面部与查询的匹配程度。

总结一下:以更加数学的方式开发您的业务逻辑,因为这样您可以更自由地在以后扩展系统,并且还可以避免让您头疼,因为您不必为每个功能都考虑好名称。并制作一个漂亮的GUI,这样用户就不必输入复杂的数学公式。

答案 2 :(得分:0)

课程的大小应该是它自己的问题。

在这种情况下,我发现我需要的是每个要素类的pack()函数,它删除了我不想存储的所有数据。然后我可以按原样存储这些类,而不必关心它们的大小。