案例研究:图像处理中的多态性
Case Study: Polymorphism for Image Processing
我正在自学数字图像处理,如果有人能评论一下这个案例是否应该使用polymorphism
或者是否有更好的类设计,我将非常感激。
基本上,2D Filter/Kernel可以是: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
。CKernel1D<T>
类可以有自己的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> &);
再次,我希望根据kernel
类型调用适当的myConvolution
方法。我怎样才能实现这样的操作?我读了一些关于Virtual Friend Function Idiom
的东西,你认为,在这种情况下应用这个成语有意义吗?
所有注释&我真的很想听听你对这个设计的看法。是否有更好的方法来设计这些功能?
由于图像分析需要大量的计算能力,因此良好的性能非常重要。每个人都知道多态性是一个伟大的东西,但当然它增加了一个运行时抽象层,所以,它比静态链接代码慢。
既然你已经在使用模板,为什么你不使用一个编译时抽象层使用模板?像STL一样,你可以把你的算法包装在类中,并通过模板参数传递它们。
我在这里贴了一个简单的例子来说明这个原理。
template <typename T, typename FUNCTOR>
class ArrayTransformer
{
public:
static void Transform(T* array, int count)
{
for (int i = 0; i < count; ++i)
FUNCTOR::Transform(array[i]);
}
template <int N>
static void Transform(T (&array)[N])
{
for (int i = 0; i < N; ++i)
FUNCTOR::Transform(array[i]);
}
};
template <typename T>
class NegateTransformer
{
public:
static void Transform(T& value)
{
value = -value;
}
};
int main()
{
int array[] = { 1, 2, 3, 4, 5, 6 };
ArrayTransformer<int, NegateTransformer<int> >::Transform(array);
....
return 0;
}
新一代编译器可以很好地优化这段代码:)开销,如果你使用一个好的编译器并且你在发布模式下编译,将为零。
当然,这是有意义的,如果你需要调用内部函子上千次,如果你只需要调用它一次,你可以使用多态性。您还可以混合使用这两种技术来获得内部循环的高性能,同时在更高级别上易于使用。
- 多态性和功能结合
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- C++boost序列化多态性问题
- 如何查找哪个类对象位于数组的特定索引上(多态性)
- 如何在多线程中正确使用unique_ptr进行多态性?
- 具有智能指针的多态性
- 在 C++ 中在堆栈上创建实例时如何保持多态性?
- 继承/多态性 - 我是否被迫使用"protected"变量?
- C++ 多态性在代码::块 17.12 中不起作用
- C++ 泛型和多态性:这种模式可行吗?
- 为什么我们实际上需要运行时多态性?
- 如何在这个简单的最小示例中实现多态性?
- 在同时处理基类的多个指针时如何处理多态性?
- JVM如何处理多态性及其优化
- 异常处理+多态性,如果异常方法在同一类中不起作用,则不起作用
- 有没有可能创建一个数组,在初始化时我们不知道元素的数量?(处理遗传/多态性)
- 在c++中使用多态性和继承来处理一篮子水果的正确方法是什么?
- 案例研究:图像处理中的多态性
- 用于智能指针(intrusive_ptr)的抽象基类-处理继承性、多态性、可克隆性和从工厂返回的方法