Ask Your Question
0

Implement imfilter(matlab) with OpenCV

asked 2013-03-08 11:25:16 -0600

carlosb gravatar image

updated 2013-07-17 07:41:48 -0600

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;
edit retag flag offensive close merge delete

Comments

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

jayrambhia gravatar imagejayrambhia ( 2013-03-08 13:00:56 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
3

answered 2013-03-08 13:38:20 -0600

awknaust gravatar image

updated 2013-03-08 13:39:14 -0600

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

edit flag offensive delete link more

Comments

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

carlosb gravatar imagecarlosb ( 2013-03-11 03:56:43 -0600 )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 ( 2015-06-24 23:56:01 -0600 )edit

Question Tools

Stats

Asked: 2013-03-08 11:25:16 -0600

Seen: 7,780 times

Last updated: Jul 17 '13