OpenCV — Resize an Image

How To Resize Without Distortion #PyVisionSeries — Episode #05

J3
Jungletronics
5 min readOct 8, 2022

--

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?
Cinerama — image borrowed from linkCinerama, a panoramic process that involved projecting on three screens made its debut in this glorified slideshow presented by Merian C. Cooper that toured the nation in 1952.

This is all about aspect ratio.

The aspect ratio of an image is the ratio of its width to its height, and is expressed with two numbers separated by a colon, such as 16:9, sixteen-to-nine. wikipedia

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, 0
print(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, 0
elif 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

--

--

J3
Jungletronics

Hi, Guys o/ I am J3! I am just a hobby-dev, playing around with Python, Django, Ruby, Rails, Lego, Arduino, Raspy, PIC, AI… Welcome! Join us!