Ask Your Question

Why filter2D rounds certain results?

asked 2018-09-21 11:11:30 -0500

e1513377 gravatar image

updated 2018-09-21 12:27:34 -0500

I have an image and filter:

image description

image description

I applied a few operations on it below. I checked the results for ratioA, and ratioB, and noticed they were the same or very close to the variables with the same names in Matlab. However, the result differs for ratio:

Mat img = imread("lenablur.bmp");
cvtColor(img, img, cv::COLOR_BGR2GRAY);
img.convertTo(img, CV_64F);
cv::Scalar s=255;
divide(img, s, img);

cv::Mat kernel = imread("PSFgauss.bmp");
cvtColor(kernel, kernel, cv::COLOR_BGR2GRAY);
kernel.convertTo(kernel, CV_64F);
cv::Scalar kernelsum = cv::sum(kernel);
divide(kernel, kernelsum, kernel);

Mat deconv=img.clone();

Mat ratio; Mat ratioA; Mat ratioB;
filter2D(deconv, ratioA, deconv.depth(), kernel, Point(-1, -1), 0,

divide(img, ratioA, ratioB);

filter2D(ratioB, ratio, ratio.depth(), kernel, Point(-1, -1), 0,
for (int r = 90; r < 93; r++) {
    for (int c = 70; c < 75; c++) {
        cout <<<double>(r, c) << " ";
    cout << endl;

the result for ratio is:

1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

The values for ratioA and ratioB were good, and they matched the values I got when using Matlab. However, for ratio the values seemed to be rounded down somehow to int values instead of remaining double. Why did this happen, especially since the values for ratioA and ratioB were not rounded down in OpenCV?

EDIT: observed and img are supposed to be the same, psf and kernel are supposed to be the same. Fixed the typos

edit retag flag offensive close merge delete


where is deconv coming from ? (you're assuming, that the result of filter2D has the same type)

also, you construct a kernel , but later use a psf . things don't match. please correct.

also: observed ? we can help you, if we can reproduce it, help us with that, please.

berak gravatar imageberak ( 2018-09-21 12:00:51 -0500 )edit

I fixed the typos as mentioned in the EDIT

e1513377 gravatar imagee1513377 ( 2018-09-21 12:27:48 -0500 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2018-09-21 12:48:42 -0500

berak gravatar image

updated 2018-09-21 13:17:42 -0500

no, filter2D() does not round anything. what you observe are errors in your code.

please NEVER write for loops like that with opencv. it's the most dangerous and silly noob ANTIPATTERN there is.

(it's also hard to get the type right (and you got it wrong, it's uchar, not double. an expectation mismatch. you should have checked the type() before applying at(), plain guessing will lead to shooting your own foot))

rather print out your Mat like:

cout << ratio(Range(90,93), Range(70,75)) << endl;

and you won't have to worry about the underlying type ever, again.

but the main problem is here:

filter2D(ratioB, ratio, ratio.depth(), kernel, Point(-1, -1), 0,
                        ratio is an *empty* (uninitialized) Mat, which defaults to type CV_8U

replacing it with :

filter2D(ratioB, ratio, CV_64F, kernel, Point(-1, -1), 0,

(and using a proper cout statement, NOT a for loop) yields the probably correct:

[1.064462175504303, 1.081087461852151, 1.093795521963379, 1.103062688483393, 1.109410216302785;
 1.096379468908243, 1.113049809562855, 1.125585710677836, 1.1345460270182, 1.140489215023692;
 1.120826367398934, 1.137233223043043, 1.149376122330102, 1.157815148607972, 1.163169752913307]
edit flag offensive delete link more



that fixed it. Thanks!

e1513377 gravatar imagee1513377 ( 2018-09-21 13:18:24 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower


Asked: 2018-09-21 11:11:30 -0500

Seen: 28 times

Last updated: Sep 21 '18