23

I'm trying to preprocess images dataset, represented in numpy array with images of shape (28, 28) by rescaling them to (10, 10). I wrote a function for that:

import cv2 as cv

def resize_dataset(images):
    resized_images = []
    for img in images:
            img = img.reshape((28,28))
            resized_img = cv.resize(img, dsize=(10, 10))
            resized_images.append(resized_img)
    return numpy.array(resized_images)

But when I actually try to rescale them, I get the following error in cv.resize:

error: OpenCV(4.0.0) /io/opencv/modules/imgproc/src/resize.cpp:3662: error: (-215:Assertion failed) func != 0 in function 'resize'

In google I only found people with the same error writing on c++ doing very different stuff, like this one: resize an image and changing its depth and this: http://answers.opencv.org/question/19715/error-215-func-0-in-function-convertto/

How do I fix it?

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
zeyger
  • 1,320
  • 1
  • 12
  • 18

4 Answers4

60

Oh, I actually figured it out. Images in the dataset were of type np.int64. I just had to convert images to float32, like this:

import numpy as np
import cv2 as cv

def resize_dataset(images):
    resized_images = []
    for img in images:
            img = img.reshape((28,28)).astype('float32')  # <-- convert image to float32
            resized_img = cv.resize(img, dsize=(10, 10))
            resized_images.append(resized_img)
    return numpy.array(resized_images)

And now it works nicely. It looks like cv.resize can't work with images represented in int. Hope this will help anyone

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
zeyger
  • 1,320
  • 1
  • 12
  • 18
  • 7
    Does anyone knows why it does not work with `int64`? I also found out that it does not work with `int32` but it does work with `uint8` – Neb Jan 15 '20 at 11:50
  • 3
    Would be nice if the error message explained this :\ – jtlz2 Jan 13 '21 at 08:16
  • 1
    I'm grateful for your sharing of solution! I'm stuck with this problem too. This is the first time I found opencv function receive only float data, but why? And I don't see this written in the document. – 林彥良 Jun 13 '21 at 13:39
  • The reason why uint8 is accepted is because the range 0 to 255 can be represented with 8 bits, its that its working with float32. – Vinayak Mikkal Jun 26 '22 at 04:14
7

Actually cv2.resize can work with images represented in integer, but you need to change the default interpolation method.

Here are listed the different Interpolation flags you can use : OpenCV resize interpolation flags.

By default, cv2 uses the INTER_LINEAR method that, as its name suggests, is linear. So, most of the time it leads to give you values that must be represented as floats. Same with INTER_CUBIC, INTER_AREA, INTER_LANCZOS4...

But there are methods that can be applied on integers, like INTER_NEAREST (nearest neighbor) or INTER_LINEAR_EXACT (same as INTER_LINEAR, but rounded to the nearest integer).

In the aforementioned case, i would have suggested to try :

import cv2
resized_img = cv2.resize(img, (10,10), interpolation=cv2.INTER_LINEAR_EXACT)
Lue Mar
  • 442
  • 7
  • 10
  • 1
    `INTER_LINEAR_EXACT` still gives me the same error with `int32` images (OpenCV(4.5.4-dev), C++). `INTER_NEAREST` works. – fferen Jan 18 '22 at 18:49
1

I don't have an explanation for this. The solution is to have your input image in uint8 format or float32.

Using numpy, it becomes...

my_image = np.array(my_image, dtype='uint8')
Sreekant Shenoy
  • 1,420
  • 14
  • 23
0

Firstly, let's check the range of the image whether between [0 1] or not. I got an error cause my RGB in range 255.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Linh
  • 33
  • 5