Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6766885
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T14:53:06+00:00 2026-05-26T14:53:06+00:00

I’m studying Digital Image Processing by myself and would be really grateful if somebody

  • 0

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.

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

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.

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) 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.

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

(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) Now imagine, I would like to have a friend convolution function with following prototype:

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

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?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T14:53:06+00:00Added an answer on May 26, 2026 at 2:53 pm

    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.

    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.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
I would like to count the length of a string with PHP. The string
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and
I want to count how many characters a certain string has in PHP, but
For some reason, after submitting a string like this Jack’s Spindle from a text
I am trying to understand how to use SyndicationItem to display feed which is
I used javascript for loading a picture on my website depending on which small

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.