4

I noticed that when downsampling matrices in openCV using the bicubic interpolation I get negative values even though the original matrix was all positive.

I attach the following code as an example:

// Declaration of variables
cv::Mat M, MLinear, MCubic;
double minVal, maxVal;
cv::Point minLoc, maxLoc;
// Create random values in M matrix
M = cv::Mat::ones(1000, 1000, CV_64F);
cv::randu(M, cv::Scalar(0), cv::Scalar(1));
minMaxLoc(M, &minVal, &maxVal, &minLoc, &maxLoc);
// Printout smallest value in M
std::cout << "smallest value in M = "<< minVal << std::endl;

// Resize M to quarter area with bicubic interpolation and store in MCubic
cv::resize(M, MCubic, cv::Size(0, 0), 0.5, 0.5, cv::INTER_CUBIC);
// Printout smallest value in MCubic
minMaxLoc(MCubic, &minVal, &maxVal, &minLoc, &maxLoc);
std::cout << "smallest value in MCubic = " << minVal << std::endl;

// Resize M to quarter area with linear interpolation and store in MLinear
cv::resize(M, MLinear, cv::Size(0, 0), 0.5, 0.5, cv::INTER_LINEAR);
// Printout smallest value in MLinear
minMaxLoc(MLinear, &minVal, &maxVal, &minLoc, &maxLoc);
std::cout << "smallest value in MLinear = " << minVal << std::endl;

I don't understand why this happens. I noticed that if I choose random values between [0,100] the smallest value is after resizing is typically ~-24 vs. -0.24 for the range of [0,1] as in the code above.

As a comparison, in Matlab this doesn't occur (I am aware of a slight difference in weighting schemes as appears here: imresize comparison - Matlab/openCV).

Here's a short Matlab code snippet that saves the smallest value in any of 1000 random downsized matrices (original dimensions of eahc matrix 1000x1000):

currentMinVal = 1e6;
for k=1:1000        
    x = rand(1000);
    x = imresize(x,0.5);
    minVal = min(currentMinVal,min(x(:)));
end
Community
  • 1
  • 1
CV_User
  • 1,183
  • 2
  • 12
  • 20

1 Answers1

3

As you can see at this answer the bicubic kernel is not non-negative, therefore, in some cases the negative coefficients may dominate and produce negative outputs.

You should also note that Matlab is using 'Antialiasing' by default, which has an effect on the result:

I = zeros(9);I(5,5)=1; 
imresize(I,[5 5],'bicubic') %// with antialiasing
ans =
     0         0         0         0         0
     0    0.0000   -0.0000   -0.0000         0
     0   -0.0000    0.3055    0.0000         0
     0   -0.0000    0.0000    0.0000         0
     0         0         0         0         0

imresize(I,[5 5],'bicubic','Antialiasing',false) %// without antialiasing
ans =
     0         0         0         0         0
     0    0.0003   -0.0160    0.0003         0
     0   -0.0160    1.0000   -0.0160         0
     0    0.0003   -0.0160    0.0003         0
     0         0         0         0         0
Community
  • 1
  • 1
Shai
  • 111,146
  • 38
  • 238
  • 371
  • That seems reasonable. I guess it boils down to the random number generator used in Matlab vs. openCV - because in Matlab it never became negative whereas in openCV it was always producing negative values. Do you agree with that assumption (RNG)? – CV_User May 10 '15 at 09:22
  • 1
    @CV_User there is also a difference in the kernel used by OpenCv and Matlab. – Shai May 10 '15 at 09:50
  • If the kernel was non-negative in Matlab and wasn't non-negative in openCV this would be a valid explanation. However, it seems it is not non-negative in both cases yet in Matlab I don't get negative results whereas in openCV I do. This might be off-topic, but I tried editing the coefficient in imgwarp.cpp and saving it, but I guess it needs more than just a save. How does one rebuild openCV so this edit sticks? Thanks Shai! – CV_User May 11 '15 at 05:00
  • 1
    @CV_User please see my edit regarding `'Antialiasing'` option. – Shai May 11 '15 at 05:13
  • I saw that Matlab uses anti-aliasing in the other related answers before I posted my question, but didn't think of checking if Matlab yields negative values without that option. Oops... and thanks for pointing it out! I guess the only way I'll fix this is by re-building openCV, but I don't know how this is done. Guess it's time for some Googling... – CV_User May 11 '15 at 05:19
  • @CV_User building opencv is so much FUN. good luck and be strong! – Shai May 11 '15 at 05:20