OpenCV — Resize an Image
How To Resize Without Distortion #PyVisionSeries — Episode #05
The problem is quite simple: I want to take a very large image (3448x4592) and transform it into, for example,(200x200) pixels, without distorting it. How to make it?
This is all about aspect ratio.
In your social media platforms chances are that you want to repurpose one picture in various ways, on different platforms. For example, you may want to repurpose a horizontal Facebook picture on an Instagram story.
How are you going to do it?
By simply changing the aspect ratio.
Let’s get Started!
00 step # First, Let’s Showing the Problem.
Importing all the libs:
import os
import time
import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
01 step # Importing the Image to Work with
f = 'tv_laptop.jpg'
path = 'DATA/'+f
img = cv2.imread(path)
# Correcting coloring for MatPlotLib
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
i = plt.imshow(img, cmap='gray')
img.shape(3448, 4592, 3)
02 step # Showing the Problem — Trying to Do a Raw Resize :/
resized = cv2.resize(img, (200,200), cv2.INTER_AREA)
# Correcting coloring for MatPlotLib
img = cv2.cvtColor(resized, cv2.COLOR_RGB2BGR)
i = plt.imshow(img, cmap='gray')
img.shape(200, 200, 3)
03 step # Find The Size of the Original Image
# reload everything
f = 'tv_laptop.jpg'
path = 'DATA/'+f
img = cv2.imread(path)
img = img.copy()
# Correcting coloring for MatPlotLib
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
i = plt.imshow(img, cmap='gray')
img.shape
# Saving height(h) for variable h, and length for w
# Use Tuple unpacking tecnique
h, w = img.shape[:2]
print(h, w)3448 4592
04 step # What Size do You Want to Convert the Image to?
size = (200,200)
sh, sw = size
print(sh, sw)200 200
05 step # Choose an OpenCV Interpolation Method
# interpolation method
if h > sh or w > sw: # shrinking image
interp = cv2.INTER_AREA
else: # stretching image
interp = cv2.INTER_CUBIC
06 step # Calculate the Pads in case the Images are Horizontal or Vertical
# aspect ratio of image
aspect = w/h
print(f"The original aspect ratio is {aspect:.3}")# compute scaling and pad sizing
if aspect > 1: # horizontal image
new_w = sw
new_h = np.round(new_w/aspect).astype(int)
pad_vert = (sh-new_h)/2
pad_top, pad_bot = np.floor(pad_vert).astype(int),
np.ceil(pad_vert).astype(int)
pad_left, pad_right = 0, 0print(f"h={new_h}, new_w={new_w}")
# Recalc the aspect ratio
aspect = w/h
print(f"The new aspect ratio is still {aspect:.3}")
print("With this math we proportionally convert the image to 200 x 200")The original aspect ratio is 1.33
h=150, new_w=200
The new aspect ratio is still 1.33
With this math we proportionally convert the image to 200 x 200
07 step # Mount the Image with Pads, if necessary
scaled_img = cv2.resize(img, (new_w, new_h), interpolation=interp)scaled_img = cv2.copyMakeBorder(scaled_img, pad_top, pad_bot, pad_left, pad_right, borderType=cv2.BORDER_CONSTANT, value=127)i = plt.imshow(scaled_img, cmap='gray')scaled_img.shape(200, 200, 3)
08 step #Run It All Together & Check it out
import cv2
import numpy as np
def resizeAndPad(img, size, padColor=0):
h, w = img.shape[:2]
sh, sw = size
# interpolation method
if h > sh or w > sw: # shrinking image
interp = cv2.INTER_AREA else: # stretching image
interp = cv2.INTER_CUBIC# aspect ratio of image
aspect = w/h# compute scaling and pad sizing
if aspect > 1: # horizontal image
new_w = sw
new_h = np.round(new_w/aspect).astype(int)
pad_vert = (sh-new_h)/2
pad_top, pad_bot = np.floor(pad_vert).astype(int),
np.ceil(pad_vert).astype(int)
pad_left, pad_right = 0, 0elif aspect < 1: # vertical image
new_h = sh
new_w = np.round(new_h*aspect).astype(int)
pad_horz = (sw-new_w)/2
pad_left, pad_right = np.floor(pad_horz).astype(int),
np.ceil(pad_horz).astype(int) pad_top, pad_bot = 0, 0else: # square image
new_h, new_w = sh, sw
pad_left, pad_right, pad_top, pad_bot = 0, 0, 0, 0# set pad color
if len(img.shape) == 3 and not isinstance(padColor, (list, tuple,
np.ndarray)): # color image but only one color provided
padColor = [padColor]*3# scale and pad
scaled_img = cv2.resize(img, (new_w, new_h), interpolation=interp)
scaled_img = cv2.copyMakeBorder(scaled_img, pad_top, pad_bot,
pad_left, pad_right, borderType=cv2.BORDER_CONSTANT,
value=padColor)return scaled_img
Checking it out:
new_img = resizeAndPad(img, (200,200), 127)
i = plt.imshow(new_img, cmap='gray')
new_img.shape# Saving the new image inside DATA folder
filename = 'tv_laptop_resized.jpg'
# Using cv2.imwrite() method
# Saving the image
cv2.imwrite(filename, new_img)(200, 200, 3)
print("That´s it! Thank you once again!\nI hope will be helpful.")That´s it! Thank you once again!
I hope will be helpful.
👉Jupiter notebook link :)
👉Github (EX_05)
Credits & References:
Jose Portilla — Python for Computer Vision with OpenCV and Deep Learning — Learn the latest techniques in computer vision with Python, OpenCV, and Deep Learning!
https://www.videoconverterfactory.com/tips/change-aspect-ratio.html
https://elitescreens.com/understanding-aspect-ratio/
https://invideo.io/blog/aspect-ratio-for-videos/http://wiki.robotz.com/index.php/Cinema_Aspect_Ratios
https://mubi.com/films/this-is-cinerama
https://oilcity.news/community/city/2017/09/08/spectacle-cinerama-comes-casper-weekend/
Posts Related:
00 Episode# Hi Python Computer Vision — PIL! — An Intro To Python Imaging Library #PyVisionSeries
01 Episode# Jupyter-lab — Python — OpenCV — Image Processing Exercises #PyVisionSeries
02 Episode# OpenCV — Image Basics — Create Image From Scratch #PyVisionSeries
03 Episode# OpenCV — Morphological Operations — How To Erode, Dilate, Edge Detect w/ Gradient #PyVisionSeries
04 Episode# OpenCV — Histogram Equalization — HOW TO Equalize Histograms Of Images — #PyVisionSeries
05 Episode# OpenCV — Resize an image — How To Resize Without Distortion — #PyVisionSeries
07 Episode# YOLO — Object Detection — The state of the art in object detection Framework!
08 Episode# OpenCV — HaashCascate — Object Detection — Viola–Jones object detection framework — #PyVisionSeries