First time here? Check out the FAQ!

Ask Your Question
0

Implement imfilter(matlab) with OpenCV

asked Mar 8 '13

carlosb gravatar image

updated Jul 17 '13

Hello,

I am trying to port matlab code to c++ with opencv. I could import most source code but I had serious problems with the imfilter function. I was trying to use the filter2d function for c++, but It doesn't get same results between themselves. What is the difference? How I could get the same result? The source code is very simple.....

    //src_gray has one channel
    //C++ code
filter2D(src_gray, dst,-1, kernel);

    //Matlab code 
    dst = imfilter(src_gray,kernel)

Inputs: src_gray=

11    11    11    11    11
11    11    11    11    11

kernel =

 2     2
 2     2

output:

Matlab:

ans =

88    88    88    88    44
44    44    44    44    22

C++:

[88 88 88 88 88; 88 88 88 88 88]

My c++ code:

/// Initialize arguments for the filter
Point anchor( -1, -1 );
double delta = 0;
int ddepth = -1;
Mat dst;

float data[2][5] = {{11,11,11,11,11},{11,11,11,11,11}};
float kernel[2][2] = {{2,2},{2,2}};

Mat src = Mat(2, 5, CV_32FC1, &data);
Mat ker = Mat(2, 2, CV_32FC1, &kernel);

filter2D(src, dst, ddepth , ker,anchor);
cout << dst << endl;
Preview: (hide)

Comments

MATLAB seems to add some padding, I guess. Try a bigger Matrix and implement imfilter and filter2D on that.

jayrambhia gravatar imagejayrambhia (Mar 8 '13)edit

1 answer

Sort by » oldest newest most voted
3

answered Mar 8 '13

awknaust gravatar image

updated Mar 8 '13

Short answer : Matlab probably isn't doing what you want. If you look at the documentation for imfilter, it defaults to using a 0-padded border which is nonsense in most scenarios. You can specify the border type to filter2D in OpenCV by passing the last argument, borderType. BORDER_DEFAULT is BORDER_WRAP_101 (which you can read about in the documentation)

Long answer is you do this:

Point anchor( 0 ,0 );
double delta = 0;

float data[2][5] = {{11,11,11,11,11},{11,11,11,11,11}};
float kernel[2][2] = {{2,2},{2,2}};

Mat src = Mat(2, 5, CV_32FC1, &data);
Mat ker = Mat(2, 2, CV_32FC1, &kernel);
Mat dst = Mat(src.size(), src.type());

Ptr<FilterEngine> fe =  createLinearFilter(src.type(), ker.type(), ker, anchor,
        delta, BORDER_CONSTANT, BORDER_CONSTANT, Scalar(0));
fe->apply(src, dst);
cout << dst << endl;

The problem is you can pass BORDER_CONSTANT to filter2D, but it doesnt take the value the constant should be, So instead you have to create a FilterEngine object. Additionally, Matlab anchors its kernel in the top-left corner, unlike the OpenCV's default, in the center

Preview: (hide)

Comments

Thanks a lot!!! It works perfectly....

carlosb gravatar imagecarlosb (Mar 11 '13)edit

@awknaust and @carlosb, I am new to opencv and I am getting errors in the FilterEngine part. Can you please share the full code ?

lakshmi8 gravatar imagelakshmi8 (Jun 25 '15)edit

Question Tools

Stats

Asked: Mar 8 '13

Seen: 7,849 times

Last updated: Jul 17 '13