Image Processing #8 - Image Append

Occasionally, images need to be pasted horizontally or vertically. In this article, we will implement this function using the numpy function commonly used in OpenCV and PIL.



Convert image to numpy array

 The first thing you must do is to convert the image to a numpy array. This is explained at https://opencvcooking.blogspot.com/2019/11/basic-cooking-1.html.

OpenCV Image to numpy vice versa

OpenCV images (Mat) have a numpy array and can be used directly without conversion.

import cv2

img = cv2.imread("dog.jpg", cv2.IMREAD_COLOR)
print(type(img));

And you can convert numpy array to an OpenCV image using
fromarray function.

import cv2
img = cv.fromarray(array)
height, width, channels = img.shape

PIL Image to numpy vice versa


from PIL import Image
im = Image.fromarray(np.uint8(array))
array = np.asarray(im, dtype="uint8")

And you can convert numpy array to an PIL image using fromarray function(same as OpenCV).

from PIL import Image
im = Image.fromarray(np.uint8(array))
width, height = im.size


 Pasting a horizontal image

 To attach an image horizontally, the horizontal size must be the same. We will change the horizontal size of the second image based on the first image.

<elsa1.jpg                                             elsa2.jpg>

OpenCV Example

OpenCV image data(Mat) is compatible with numpy array. So you can use the data in the numpy function without any converison.


# To add a new cell, type '# %%'
# To add a new markdown cell, type '# %% [markdown]'
# %%
import cv2
import numpy as np

img = cv2.imread("F:\src\OpenCV\Image Processing #5 - Image Append\\elsa1.jpg", cv2.IMREAD_COLOR)
height1, width1, channels1 = img.shape
print("elsa1 JPG   H:%d W:%d, Channel:%d"%(height1, width1, channels1))

img2 = cv2.imread("F:\src\OpenCV\Image Processing #5 - Image Append\\elsa2.jpg", cv2.IMREAD_COLOR)
height2, width2, channels2 = img2.shape
print("elsa2 JPG   H:%d W:%d, Channel:%d"%(height2, width2, channels2))


# %%
#resize the second image. Make the same height
img3 = cv2.resize(img2, (int(width2 * height1 * 1.0 / height2), height1))
height2, width2, channels2 = img3.shape
print("elsa2 resized JPG   H:%d W:%d, Channel:%d"%(height2, width2, channels2))

#resize the second image. Make the same width
img4 = cv2.resize(img2, (width1, int(height2 * width1 * 1.0 / width2) ))
height3, width3, channels3 = img4.shape
print("elsa2 resized JPG   H:%d W:%d, Channel:%d"%(height3, width3, channels3))


# %%
imgs_combH = np.hstack((img, img3 ))
height, width, channels = imgs_combH.shape
print("elsa combined JPG   H:%d W:%d, Channel:%d"%(height, width, channels))

imgs_combV = np.vstack((img, img4 ))
height, width, channels = imgs_combV.shape
print("elsa combined JPG   H:%d W:%d, Channel:%d"%(height, width, channels))


# %%
cv2.imshow('elsa1', img)
cv2.imshow('elsa2', img3)
cv2.imshow('elsa3', imgs_combH)
cv2.imshow('elsa4', imgs_combV)
cv2.waitKey(0)
cv2.destroyAllWindows()


# %%


PIL Example

PIL image format must be converted to numpy array before using hstack, vstack functions.


# To add a new cell, type '# %%'
# To add a new markdown cell, type '# %% [markdown]'
# %%
from PIL import Image
import numpy as np


img = Image.open("F:\src\OpenCV\Image Processing #5 - Image Append\\elsa1.jpg")
width1, height1 = img.size
print("elsa1 JPG   H:%d W:%d"%(height1, width1))

img2 = Image.open("F:\src\OpenCV\Image Processing #5 - Image Append\\elsa2.jpg")
width2, height2 = img.size
print("elsa2 JPG   H:%d W:%d"%(height2, width2))


# %%
#resize the second image. Make the same height
img3 = img2.resize((int(width2 * height1 * 1.0 / height2), height1))
width2, height2  = img3.size
print("elsa2 resized JPG   H:%d W:%d"%(height2, width2))

#resize the second image. Make the same width
img4 = img2.resize((width1, int(height2 * width1 * 1.0 / width2) ))
width3, height3 = img4.size
print("elsa2 resized JPG   H:%d W:%d"%(height3, width3))

np_img3 = np.asarray(img3, dtype="uint8")
np_img4 = np.asarray(img4, dtype="uint8")


# %%
combH = np.hstack((img, np_img3 ))
imgs_combH = Image.fromarray(np.uint8(combH))
width, height = imgs_combH.size
print("elsa combined JPG   H:%d W:%d"%(height, width))

combV = np.vstack((img, np_img4 ))
imgs_combV = Image.fromarray(np.uint8(combV))
width, height  = imgs_combV.size
print("elsa combined JPG   H:%d W:%d"%(height, width))


# %%
img.show()
img3.show()
imgs_combH.show()
imgs_combV.show()


# %%


Wrapping up

The numpy hstack and vstack functions make it easy to paste images horizontally or vertically. In the example above, two images are connected, but multiple images can be connected at once by putting multiple images in the tuple parameter of hstack and vstack.



















댓글

이 블로그의 인기 게시물

Image Processing #7 - OpenCV Text

Playing YouTube videos using OpenCV

OpenCV Installation - Rasbian Buster, Jessie, DietPi Buster