私は自分でデジタル画像処理を勉強していますが、polymorphism
をこのアプリケーションに適用する必要があるかどうか、またはより優れたクラスデザインがあるかどうかを誰かがコメントできれば本当に感謝します。ケーススタディ:画像処理の多態性
基本的に、2Dフィルタ/カーネルは、non-separable
またはseparable
のいずれかです。重要なカーネル操作はconvolution
であり、計算方法はフィルターの種類によって異なります。でもCSeparableKernel2D
クラスは、2つのプライベートメンバを持つことができ
template < typename T >
class CKernel2D{
public:
//....
virtual CMatrix<T> myConvolution(const CMatrix<T> & input) = 0;
//....
};
template < typename T >
class CNonSeparableKernel : public CKernel2D<T> {
public:
//....
CMatrix<T> myConvolution(const CMatrix<T> & input);
void initNonSeparableFilter1(double, int );
//....
private:
CMatrix<T> m_Kernel;
};
template < typename T >
class CSeparableKernel2D : public CKernel2D<T>{
public:
//....
CMatrix<T> myConvolution(const CMatrix<T> & input);
void initSeparableFilter1(double, double);
//....
private:
std::vector<T> m_KernelX;
std::vector<T> m_KernelY;
};
注:CKernel1D<T> m_X, m_Y
。 CKernel1D<T>
クラスは、独自のmyConvolution
メソッドを持つことができます。つまり、myConvolutionRows
,myConvolutionCols
です。
また、通常は、与えられた画像にfilters
(分離可能/分離不可能)のセットを適用したい、すなわち、入力画像が与えられた場合にはfilter
と畳み込みます。したがって、filter type
に応じて、対応するmyConvolution
メソッドを呼び出す必要があります。
(1)sthを行うには、最もクリーンな方法が必要です。好き?
CNonSeparableKernel<float> myNonSepFilter1;
myNonSepFilter1.initNonSeparableFilter1(3.0, 1);
CNonSeparableKernel<float> mySepFilter1;
mySepFilter1.initSeparableFilter1(0.5, 0.5);
std::vector<CKernel2D<float> > m_vFilterbank;
m_vFilterbank.push_back(myNonSepFilter1); // Would like to assign a non-sep filter.
m_vFilterbank.push_back(mySepFilter1); // Would like to assign a sep filter.
これを行う唯一の方法は、ポリモフィズムを使用することです。
CKernel2D<float> * pKernel2d = NULL;
pKernel2d = &mySepFilter1; m_vFilterbank.push_back(*pKernel2d);
pKernel2d = &myNonSepFilter1; m_vFilterbank.push_back(*pKernel2d);
(2)今、私たちのfilterbank
がすでに入力画像に畳み込みを適用するには、カーネルの両方のタイプで満たされ、それを行うには十分だろうと仮定:
outputSeparable1 = m_vFilterbank.at(0).myConvolution(input);
outputNonSeparable1 = m_vFilterbank.at(1).myConvolution(input);
(3)今、私は、次のプロトタイプを持つ友人convolution
機能がしたい、と想像:私は希望、再び
friend CMatrix<T> convolution(const CKernel2D<T> &, const CImage<T> &);
をその適切なmyConvolution
メタodはkernel
タイプに応じて呼び出されます。どのように私はそのような操作を達成できますか?私はsthを読む。 Virtual Friend Function Idiom
については、そのような場合にそのイディオムを適用することは理にかなっていると思いますか?
すべてのコメント&提案は本当に歓迎されています;-)私は本当にこのデザインについてどう思いますか聞いてみたいと思いますか?これらの機能を設計するためのより良い方法はありますか?
あなたの投稿に感謝します。私は静的にリンクされたコードを使ったことは一度もありません。さらに、私の場合、 'NegateTransformer'のようなクラスは、例えば、特定の'カーネル型 'に対応します。 'Transform'メソッドは' convolution'であり、 'ArrayTransformer'は' Kernel2D 'でしょうか? –
Tin
@マーク、多形関数は、 'カーネル畳み込み 'ごとに1回だけ呼び出されます。 'implementation'では、ピクセルを処理するいくつかの入れ子になったループがあります。 – Tin