我正在学习数字图像处理,如果有人能评论polymorphism
是否适用于这种情况,或者是否有更好的类设计,我将非常感激。案例研究:图像处理的多态性
基本上,2D滤镜/内核可以是:non-separable
或separable
。一个重要的内核操作是convolution
以及计算它的方式取决于过滤器类型。
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;
};
注意,即使是CSeparableKernel2D
类可以有两个私有成员:CKernel1D<T> m_X, m_Y
。类别可以有其自己的myConvolution
方法,即myConvolutionRows
,myConvolutionCols
。另外,通常,我们希望对给定图像应用一组filters
(可分离/不可分离),即将输入图像与给定的filter
进行卷积。因此,根据filter type
,应该调用相应的myConvolution
方法。
(1)哪一种应该是最干净的方式能够做到的事情。喜欢?
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
类型。我怎么能实现这样的操作?我读了某事。关于Virtual Friend Function Idiom
,你认为在这种情况下应用这个习语是否合理?
所有评论&建议真的很受欢迎;-)我真的很想听听你对这个设计有什么看法?有没有更好的方法来设计这些功能?
感谢您的帖子。我从来没有使用静态链接的代码,现在看看。而且,就我而言,像'NegateTransformer'这样的类可以对应一个特定的'kernel type',对吧? 'Transform'方法就是'卷积'和'ArrayTransformer',它可以看到整个图片,然后是'Kernel2D',对吧? –
Tin
@Mark,这个多态函数每个'kernel convolution'只调用一次。在'implementation'中,我有一些嵌套循环来处理像素。 – Tin