提取特征.一个班级里有很多getter/setters正常吗?

Extracting features. Is it normal to have a lot of getters/setters in a class?

本文关键字:getter setters 常吗 特征 一个 提取      更新时间:2023-10-16

我有一堆不同的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的项目。

许多getter和setter本身并不是糟糕设计的标志。但是,它们可能暗示您的类可以分解为较小的类。以"客户"为例,如果您将所有名称,地址,送货地址字段放在一个类中,那将是一个糟糕的设计,您应该使用"地址"类进行拆分。

我不确定你的设计是关于什么的,关键是如果你需要 100 个 getter,因为你有 100,不相关的字段使用 100 个 getters

你可能应该少考虑一些关于你的特征的literal,而更多地考虑抽象和数学术语。您似乎将面部描述为面部特征的组合,每个面部特征都使用某种过程计算,因此每个单独的面部特征为单个特征向量贡献一个(或可能几个)标量值。因此,我建议将您的特征存储为:向量。使用一些向量类(std::vector 可能有效,但出于我将在下面解释的原因,您可以考虑使用线性数学库)。

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

现在,您仍然应该以某种方式表达您的搜索查询。与其使用 getter 和 setter,不如在向量中重写搜索查询,例如,您可以采用距离(欧几里得、曼哈顿)来计算存储的人脸与查询的匹配程度。

总而言之:以更数学的方式开发您的业务逻辑,因为这可以让您更自由地在以后扩展系统,并且还可以避免麻烦,因为您不必为每个功能想出好的名字。并制作一个漂亮的GUI,这样用户就不必输入复杂的数学公式。

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

在本例中,我发现我所需要的只是为每个要素类提供一个pack()函数,该函数可移除我不想存储的所有数据。然后,我可以按原样存储类,而不必关心它们的大小。