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 :].