In this post, I will explain how to read multiple images from a folder, resize them, save them in a new folder (retaining the same names in the file) and display them one by one. All the images will be at first, cropped in centre and then will be placed in the centre of a canvas. The image background is removed using grayscale, Gaussian blur, Otsu’s threshold.
First, we will import the required libraries.
import cv2 import glob import os import numpy as np
Now to resize images, we will make a new output folder, read images from the input folder one by one using a for loop, resize the images, save them in the output folder and display resized images one by one.
import cv2
import glob
import os
import numpy as np
canvas = 256
inputFolder = 'images'
folderLen = len(inputFolder)
if not os.path.exists('Resized'):
os.makedirs('Resized')
def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
dim = None
(h, w) = image.shape[:2]
if width is None and height is None:
return image
if width is None:
r = height / float(h)
dim = (int(w * r), height)
else:
r = width / float(w)
dim = (width, int(h * r))
# resize the image
resized = cv2.resize(image, dim, interpolation = inter)
return resized
i=0
for imgg in glob.glob(inputFolder + "/*.jpg"):
# Load image, grayscale, Gaussian blur, Otsu's threshold
image = cv2.imread(imgg)
# Apply Binary Thresholding to remove background
ret,image = cv2.threshold(image,200,255,cv2.THRESH_BINARY)
original = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (25,25), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Perform morph operations, first open to remove noise, then close to combine
noise_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, noise_kernel, iterations=2)
close_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7))
close = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, close_kernel, iterations=3)
# Find enclosing boundingbox and crop ROI
coords = cv2.findNonZero(close)
x,y,w,h = cv2.boundingRect(coords)
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
crop = original[y:y+h, x:x+w]
cv2.imwrite('crop.png', crop)
white_canvas = np.zeros([canvas,canvas,1],dtype=np.uint8)
white_canvas.fill(255)
cv2.imwrite('white.png', white_canvas)
# load resized image as grayscale
img = cv2.imread('crop.png', cv2.IMREAD_GRAYSCALE)
img = image_resize(img, width = canvas)
h, w = img.shape
# load background image as grayscale
back = cv2.imread('white.png', cv2.IMREAD_GRAYSCALE)
hh, ww = back.shape
# compute xoff and yoff for placement of upper left corner of resized image
yoff = round((hh-h)/2)
xoff = round((ww-w)/2)
# use numpy indexing to place the resized image in the center of background image
result = back.copy()
result[yoff:yoff+h, xoff:xoff+w] = img
result = cv2.cvtColor(result,cv2.COLOR_GRAY2RGB)
# save resulting centered image
cv2.imwrite("Resized" + imgg[folderLen:], result)
i += 1
Now in this code, we are reading images form inputFolder, Creating a new folder Resized.
i = 0 will be used to rename images that we save in Resized folder.
In for loop, we are reading images one by one using cv2.imread
cv2.resize is used to resize the images.
cv2.imwrite is used to write the resized images to the output folder, i = 0 that we defined earlier is used here to rename the images.
image_resize function will be used to resize the image, keeping the aspect ratio.
When we will read the input images in ‘img’, it will also contain the name of the folder in which they are located, i.e, complete path of the image, and to get the name of image we have to remove the name of input folder from it so folderLen is length of the name of inputFolder, and in cv2.imwrite we are removing it and only getting the names of images at img[folderLen :].

