cv2.resize is different from scikit-image resize

asked 2020-06-18 03:49:12 -0600

Rok gravatar image

updated 2020-06-18 10:09:25 -0600

I'm trying to reproduce the same output with these snippets:

Scikit-Image + Keras

from keras.models import model_from_json
import numpy as np
from skimage.io import imread
from skimage.transform import resize

image = resize(imread(img_path, as_grey=False), (80, 80), preserve_range=True, mode='constant')
image /= 255.
img_array = np.array([image])
pred_IN = model.predict(img_array)

OpenCV

import cv2

model = cv2.dnn.readNet('mynet.prototxt', 'mynet.caffemodel')
image = cv2.imread(image_path)
img = cv2.dnn.blobFromImage(image, scalefactor=(1.0/255.0), size=(80, 80), swapRB=True, crop=False)
model.setInput(img)
pred = model.forward()

The problem is that I cannot get the same data to pass to the network (DNN module in case of OpenCV). Network is the same, input data is the same, but the results is slightly different and the reason is that resize function behaves differently between scikit-image and OpenCV (used internally by blobFromImage) and don't know how to adapt the OpenCV code to match scikit-image.

My final application will use OpenCV in C++, so I need to match this snippets, as my network has been trained with data generated by scikit-image.

EDIT

I think the problem is that Resize function of OpenCV (used internally by blobFromImage) produce a different result from scikit-image resize (I'm not saying is bugged, just want to obtain same results bewteen OpenCV and Sciki-Image, doing something in one or in another), for example for this image:

image description

image32 = cv2.imread(image).astype(np.float32)
cv2.cvtColor(image32,cv2.COLOR_BGR2RGB,image32)
new_image = cv2.resize(image32,(80,80),interpolation=cv2.INTER_LINEAR)

Upper left pixel value is: 145.91113, 76.853516, 92.67676 But with scikit-image:

img = resize(imread(img_path, as_grey=False), (80, 80), preserve_range=True, mode='constant')

Upper left pixel value is: 144.09179688, 75.74609375, 9.85742188

Scikit image uses by default interpolation bi-linear, the same used by OpenCV, so it should be the same, I also tried every possible value for parameter mode, I can never obtain the same result between scikit and OpenCV.

Altough the values seems only slightly different, when passed to the network, the network produce a different result, which I noticed can be up to 12% in classification probalility. (In this case is only 3%, top class has 0.7 with scikit + Keras and 0.66 with OpenCV).

edit retag flag offensive close merge delete

Comments

but the results is slightly different

can you explain, how so ?

berak gravatar imageberak ( 2020-06-18 04:10:35 -0600 )edit
1

can you try a direct comparison between scikit's and opencv's resize() function ?

maybe it's just the INTER_LINEAR used in blobFromImage()

berak gravatar imageberak ( 2020-06-18 04:42:04 -0600 )edit

Are you sure your difference is related to the resize function? I am not sure about that. To make sure - test with input which was explicitly resized with scikit before. And then call blobFromImage with exact the image dimensions - so no resize is done.

holger gravatar imageholger ( 2020-06-18 07:33:03 -0600 )edit

I mean in worst case you could resize the image with skit learn before feeding it to opencv - maybe its stupid. But if it works...

holger gravatar imageholger ( 2020-06-18 14:12:50 -0600 )edit

@holger I can not.. because my final application is in C++, there is no scikit-learn there. I just want to be sure if I can get the same result or no.. then I will choose one option or another.

Rok gravatar imageRok ( 2020-06-21 14:07:55 -0600 )edit
  • preserve_range=True -- opencv does not do/have this feature
  • mode='constant' -- default in opencv is BORDER_REFLECT (so, for sure, this will affect the pixel you sample at (0,0) )
berak gravatar imageberak ( 2020-06-21 15:02:45 -0600 )edit
1

@Rok, -- did you actually train that model ? would there be a possibility to redo the training with preprocessing it in a more "opencv friendly" way ?

berak gravatar imageberak ( 2020-06-21 15:13:45 -0600 )edit

Hmm w this is possible - but it would really piss me off just to retrain for this - on the other hand - shouldnt the model be more robust to such minor changes?

holger gravatar imageholger ( 2020-06-22 17:45:53 -0600 )edit

Maybe beraks suggestion with retraining is a bit time consuming but it could solve the issue - so if you could do it and maybe even mix it together with the skit resized images - this would make your model more robust. In the end it could also be some image library issues - you never really know.

holger gravatar imageholger ( 2020-06-22 19:01:24 -0600 )edit