2

Feature画像の特徴を計算するさまざまなクラスがたくさんあります。
これらのクラスから、検索キーとして一緒にパックされて使用される「キー機能」を抽出する必要があります。また、クラス
の一部も保存します。Feature非常に非効率的であるため、フィーチャクラス全体を保存することはできません。

さて、私が考えたのはStored_features、「主な機能」をまとめたクラスを書くことです。
私のレイアウトは次のとおりです。

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

私の問題は、そのようなStored_featuresクラスには多くのゲッターとセッターがあり、私が知る限り、ゲッターとセッターは悪い設計を示しているということです。ここでゲッターやセッターが多すぎるのを避けるための簡単に保守できる方法はありますか?

重要なのは、私のコードがこのレイアウトと非常に緊密に結合されているのを見るということです:(

編集:

要求に応じてコードを抽出します。

#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を追加しました。

4

3 に答える 3

2

多くのゲッターとセッターは、それ自体が悪い設計を示しているわけではありません。ただし、クラスをより小さなクラスに因数分解できるヒントになる可能性があります。'customer' を例にとると、名前、住所、配送先住所のすべてのフィールドを 1 つのクラスに入れると、設計がうまくいかないため、'address' クラスを使用して分割する必要があります。

私はあなたのデザインが何であるかわかりません。要点は、100個のゲッターが必要な場合、無関係なフィールドは100個のゲッターを使用するということです

于 2012-11-12T19:31:37.533 に答える
1

おそらく、機能についてはいくらか考える必要はなくliteral、抽象的で数学的な用語で考える必要があります。あなたは顔を顔の特徴の組み合わせとして説明しているようです。それぞれが何らかの手順を使用して計算され、それぞれの個別の顔の特徴が 1 つの (またはいくつかの) スカラー値を単一の特徴ベクトルに寄与します。したがって、特徴をベクトルとして保存することをお勧めします。いくつかのベクトル クラスを使用します (std::vector は機能する可能性がありますが、以下で説明する理由により、線形数学ライブラリの使用を検討する場合があります)。

extract必要に応じて、これらのベクトルから顔の特徴をスカラー化することもできます。たとえば、特徴がある場合、これは次元の列特徴ベクトルNに保存できます。これで、任意の線形抽出演算子を行ベクトルまたは行列として記述し、目的の機能を として取得できます。これらの行列とベクトルを保存する場合は、Boost uBLAS などのライブラリを使用することをお勧めします。NxAff = A*x

ここで、何らかの方法で検索クエリを表現する必要があります。getter と setter を使用する代わりに、検索クエリもベクトルに書き直す必要があります。たとえば、距離 (ユークリッド、マンハッタン) を使用して、保存された顔がクエリとどの程度一致するかを計算できます。

要約すると、より数学的な方法でビジネス ロジックを開発します。これにより、後でシステムを拡張する自由度が高まり、機能ごとに適切な名前を考える必要がないため、頭痛の種も減ります。そして、ユーザーが複雑な数式を入力する必要がないように、素敵な GUI を作成してください。

于 2012-11-12T20:23:16.153 に答える
0

クラスのサイズはそれ自身の問題でなければなりません。

この場合、必要なのは、pack()保存したくないすべてのデータを削除する各フィーチャクラスの関数であることがわかりました。そうすれば、クラスをそのまま保存でき、サイズを気にする必要がありません。

于 2012-11-14T14:32:52.360 に答える