Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error while resizing image: "error: (-215:Assertion failed) func != 0 in function 'resize'"

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?

like image 954
zeyger Avatar asked Mar 30 '19 06:03

zeyger


3 Answers

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

like image 156
zeyger Avatar answered Nov 14 '22 00:11

zeyger


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)
like image 6
Lue Mar Avatar answered Nov 13 '22 23:11

Lue Mar


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')
like image 1
Sreekant Shenoy Avatar answered Nov 14 '22 00:11

Sreekant Shenoy