Resizing images into squares with OpenCV and Python

Mathias Pfeil

Author

General Programming

Category

October 30 2019

Time Created

The resize method in OpenCV does not account for aspect ratio, and as a result our output image is simply stretched to size. This is okay for some simple machine learning tasks, like an image classifier for dogs and cats, but let’s say we want to train a GAN. Our results might look odd if the training data is stretched, so we need to create a uniform shape for our data without destroying the perspective. Below is a small script which will do just that.




import cv2
import os
import numpy as np

i = 1
img_size = 128

path = './collection/images/'

for img_name in os.listdir(path):
    try:
        img = cv2.imread(os.path.join(path, img_name))

        h, w = img.shape[:2]
        a1 = w/h
        a2 = h/w
  
        if(a1 > a2):
      
            # if width greater than height
            r_img = cv2.resize(img, (round(img_size * a1), img_size), interpolation = cv2.INTER_AREA)
            margin = int(r_img.shape[1]/6)
            crop_img = r_img[0:img_size, margin:(margin+img_size)]

        elif(a1 < a2):
          
            # if height greater than width
            r_img = cv2.resize(img, (img_size, round(img_size * a2)), interpolation = cv2.INTER_AREA)
            margin = int(r_img.shape[0]/6)
            crop_img = r_img[margin:(margin+img_size), 0:img_size]

        elif(a1 == a2):
          
            # if height and width are equal
            r_img = cv2.resize(img, (img_size, round(img_size * a2)), interpolation = cv2.INTER_AREA)
            crop_img = r_img[0:img_size, 0:img_size]
        
        if(crop_img.shape[0] != img_size or crop_img.shape[1] != img_size):
          
            crop_img = r_img[0:img_size, 0:img_size]

        if(crop_img.shape[0] == img_size and crop_img.shape[1] == img_size):
          
            print("Saving image with dims: " + str(crop_img.shape[0]) + "x" + str(crop_img.shape[1]))
            cv2.imwrite("collections/128/" + str(i) + '.jpg', crop_img)
            i += 1

    except:
        print('Could not save image.')



All we need to do is specify the path to our dataset, the image size, and the output path. If we set img_size to 128, all of the images will be turned into 128x128 images.


I hope this helps or saves you a bit of time. If you have any issues, please contact me through the contact form on this website. Thanks for reading!