案例研究:图像处理的多态性 [英] Case Study: Polymorphism for Image Processing

查看:206
本文介绍了案例研究:图像处理的多态性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习数字图像处理,如果有人可以评论多态性应该适用于这种情况,或者如果有一个更好的类设计,将非常感谢。

I'm studying Digital Image Processing by myself and would be really grateful if somebody could comment whether polymorphism should be applied for this case or if there's a better class design.

基本上,2D过滤器/内核可以是:不可分离 。一个重要的内核操作是卷积和计算它的方式,取决于过滤器类型。

Basically, a 2D Filter/Kernel can be either: non-separable or separable. An important kernel operation is the convolution and the way to compute it, depends on the filter type.

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

Note that even the CSeparableKernel2D class could have two private members: CKernel1D<T> m_X, m_Y. The CKernel1D<T> class could have its own myConvolution method, i.e. myConvolutionRows, myConvolutionCols.

此外,通常,我们要应用一组过滤器(可分离/不可分离)到给定图像上,即卷积输入图像与给定的过滤器。因此,根据过滤器类型,应调用相应的 myConvolution 方法。

Also, usually, we would like to apply a set of filters (separable/non-separable) onto a given image, i.e. convolve an input image is with a given filter. Therefore, depending on the filter type, the corresponding myConvolution method should be called.

(1)哪一个应该是最干净的方式能够做sth。喜欢?

(1) Which should be the cleanest way to be able to do sth. like?

 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.

在我看来,唯一的方法是使用polimorphism, >

It seemed to me that the only way to do that is by using polimorphism, right?

CKernel2D<float> * pKernel2d = NULL;
pKernel2d = &mySepFilter1; m_vFilterbank.push_back(*pKernel2d);
pKernel2d = &myNonSepFilter1; m_vFilterbank.push_back(*pKernel2d);

现在假设我们的 filterbank 已经填充了两种类型的内核,要对输入图像应用卷积,就足够了:

(2) Now assuming that our filterbank is already filled with both type of kernels, to apply the convolution on an input image, it would be enough to do:

outputSeparable1    = m_vFilterbank.at(0).myConvolution(input);
outputNonSeparable1 = m_vFilterbank.at(1).myConvolution(input);

(3)现在想象一下,我想有一个朋友 convolution 函数具有以下原型:

(3) Now imagine, I would like to have a friend convolution function with following prototype:

friend CMatrix<T> convolution(const CKernel2D<T> &, const CImage<T> &);

我想要正确的 myConvolution 方法根据 kernel 类型调用。我该如何实现这样的操作?我读sth。关于虚拟朋友功能惯用语,你认为,这样的情况下应用这种习惯会有意义吗?

again, I would like that the proper myConvolution method is called depending on the kernel type. How could I achieve such operation? I read sth. about the Virtual Friend Function Idiom, do you think, it would make sense to apply that idiom for such a case?

所有评论建议真的欢迎;-)我真的很想听听你对这个设计有什么看法?

All comments & suggestions are really welcomed ;-) I would really love to hear what do you think about this design? Is there a better way to design those functionalities?

推荐答案

由于图像分析需要大量的计算能力,良好的性能是进口商。
每个人都知道多态是一个伟大的东西,但当然它添加了运行时抽象层,所以,它比静态链接代码慢。

Since image analysis requires a lot of computational power, good performances are importants. Everyone know that polymorphism is a great stuff but of course it adds a runtime abstraction layer, so, it is slower than statically linked code.

已经使用模板为什么你不使用编译时间抽象层使用模板?像STL一样,你可以在类中包装你的算法,并通过模板参数传递它们。

Since you are already using templates why you don't use a compile time abstraction layer using templates? Like STL does, you can wrap your algorithms in classes and pass them through template parameters.

我在这里张贴一个简单的例子来显示原理。

I post here a simple example to show the principle.

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;
}

新一代编译器可以优化此代码很好:)开销,如果你正在使用一个好的编译器,并且在发布模式下编译,将为零。

New generation compilers can optimize this code quite well :) the overhead, if you are using a good compiler and you compile in release mode, will be zero.

当然,如果你必须调用内部函子千次,必须调用它只有一次,你可以只使用多态性。
您还可以混合这两种技术,以获得内部循环中的高性能,同时在较高级别方便易用性。

Of course this makes sense if you have to call the inner functor thousand of times, if you have to call it only once you can just use polymorphism. You can also mix both techniques to obtain high performance in inner loops and in the same time easy usability at higher level.

这篇关于案例研究:图像处理的多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆