How to merge images after spliting into grids? - python

I'm trying to split single image into multiple grids in order to reduce dimension and do some image processing on that and then combine back splitted image to single image.
currently Im splitting single image into 72 multiple grids as shown in below code
from imutils import paths
from PIL import Image
from itertools import product
import os
source_path = r'D:\Data\images'
dest_path = r'D:\Data\cropped_data\\'
all_images = list(paths.list_images(source_path))
for img_path in all_images:
img = Image.open(img_path)
w,h = img.size
d = 500
grid = product(range(0, h-h%d, d), range(0, w-w%d, d))
file_name = img_path.split('\\')[-1].split('.')[0]
print(file_name)
save_path = dest_path+file_name
print(save_path)
os.makedirs(save_path,exist_ok=True)
for i, j in grid:
box = (j, i, j+d, i+d)
out = save_path+'\\'+'cropped'+f'_{i}_{j}'+'.jpg'
print(out)
img.crop(box).save(out)
above code snippet crop image into 72 mulitple grids and saves it in folder, I'm doing some preprocessing and saving it in same folder, I want to merge these images again back to original size in same sequence , I'm trying below code to achieve this
import glob
from PIL import Image
from itertools import product
all_images = glob.glob(r'splitted_image_folder\*.png')
d = 500
w = 6016
h = 3376
new_im = Image.new('RGB',(w,h),(250,250,250))
grid = product(range(0,h-h%d,d),range(0,w-w%d,d))
for u,(i,j) in enumerate(grid):
img = Image.open(all_images[u])
new_im.paste(img,(i,j))
new_im.save("merged_img.png","PNG")
executing this code merge only half of images at the first half of image and leaving other half in white,instead of merging all grid images it only pasting half of the images , I'm not able to understand why its missing other half .
Any guide or suggestion to achieve this will be appreciated

Related

Python collage of four image together

I am trying to combine 4 images, image 1 on top left, image 2 on top right, image 3 on bottom left and image 4 on bottom right. However, my images are different sizes and not sure how to resize the images to same size. I am pretty new to Python and this is my first time using PIL.
I have this so far (after opening the images)
img1 = img1.resize(img2.size)
img1 = img1.resize(img3.size)
img1 = img1.resize(img4.size)
This shall suffice your basic requirement.
This shall suffice your basic requirement.
Steps:
Images are read and stored to list of arrays using io.imread(img) in
a list comprehension.
We resize images to custom height and width.You can change IMAGE_WIDTH,IMAGE_HEIGHT as per your need with respect
to the input image size.
You just have to pass the location of n
images (n=4 for your case) to the function.
If you are
passing more than 2 images (for your case 4), it will work create 2
rows of images. In the top row, images in the first half of the list
are stacked and the remaining ones are placed in bottom row using
hconcat().
The two rows are stacked vertically using vconcat().
Finally, we convert the result to RGB image using
image.convert("RGB") and is saved using image.save().
The code:
import cv2
from PIL import Image
from skimage import io
IMAGE_WIDTH = 1920
IMAGE_HEIGHT = 1080
def create_collage(images):
images = [io.imread(img) for img in images]
images = [cv2.resize(image, (IMAGE_WIDTH, IMAGE_HEIGHT)) for image in images]
if len(images) > 2:
half = len(images) // 2
h1 = cv2.hconcat(images[:half])
h2 = cv2.hconcat(images[half:])
concat_images = cv2.vconcat([h1, h2])
else:
concat_images = cv2.hconcat(images)
image = Image.fromarray(concat_images)
# Image path
image_name = "result.jpg"
image = image.convert("RGB")
image.save(f"{image_name}")
return image_name
images=["image1.png","image2.png","image3.png","image4.png"]
#image1 on top left, image2 on top right, image3 on bottom left,image4 on bottom right
create_collage(images)
To create advanced college make you can look into this:
https://codereview.stackexchange.com/questions/275727/python-3-script-to-make-photo-collages

How to find possible permutation of a list that contains images?

I am trying to load an image using opencv and then splitting that image into 4 parts. I have saved all the images in a list and now i want to find out all the possible permutation combination.
This is my current code.
#Importing Libraries
import cv2 as cv
import numpy as np
import glob
import itertools
#Importing Image
path = 'cat.jpg'
img = cv.imread(path)
#Seperating the height and width from the image data
(h, w) = img.shape[:2]
#Finding the center
centerX, centerY = (w//2), (h//2)
#spliting the image
topleft = img[0:centerY, 0:centerX]
topright = img[0:centerY, centerX:w]
bottomleft = img[centerY:h, 0:centerX]
bottomright = img[centerY:h, centerX:w]
#creating a new directory
os.mkdir('splits')
#Saving split images
cv.imwrite('./splits/1.jpg', topleft)
cv.imwrite('./splits/2.jpg', topright)
cv.imwrite('./splits/3.jpg', bottomleft)
cv.imwrite('./splits/4.jpg', bottomright)
#Putting the images in a list
img_data = []
files = glob.glob ('./splits/*.jpg')
for myfile in files:
image = cv.imread(myfile)
img_data.append(image)
I have tried to use the permutation function from the itertools library. But i don't think so it is working properly.
I expaneded you code a little bit, ran this and it worked for me:
#Importing Libraries
import cv2 as cv
import glob
import os
from itertools import permutations
#Importing Image
path = 'cat.jpg'
img = cv.imread(path)
#Seperating the height and width from the image data
(h, w) = img.shape[:2]
#Finding the center
centerX, centerY = (w//2), (h//2)
#spliting the image
topleft = img[0:centerY, 0:centerX]
topright = img[0:centerY, centerX:w]
bottomleft = img[centerY:h, 0:centerX]
bottomright = img[centerY:h, centerX:w]
def concat_tile(im_list_2d):
return cv.vconcat([cv.hconcat(im_list_h) for im_list_h in im_list_2d])
#creating a new directory
try:
os.mkdir('splits')
os.mkdir("./permutations")
except:
pass
#Saving split images
cv.imwrite('./splits/1.jpg', topleft)
cv.imwrite('./splits/2.jpg', topright)
cv.imwrite('./splits/3.jpg', bottomleft)
cv.imwrite('./splits/4.jpg', bottomright)
#Putting the images in a list
img_data = []
files = glob.glob ('./splits/*.jpg')
print(files)
c = 0
for elem in permutations(files):
perm_file = None
im0 = cv.imread(elem[0])
im1 = cv.imread(elem[1])
im2 = cv.imread(elem[2])
im3 = cv.imread(elem[3])
im_tile = concat_tile([[im0, im1], [im2, im3]])
cv.imwrite(f"permutations/perm_{c}.jpg", im_tile)
c += 1
Ran into some trouble with creating the permutations folder locally, but you can work around that yourself and create it manually for now.
I have 24 files that are permutations like you described:
Also, here's how one of them looks:
Note the vconcat function and the user of permutations.
You can, of course, use a better description for you file names by splitting the path string, but that's easy.
Good luck!

cropping and slicing multiple images in a folder using python PIL or cv2, then saving in another folder

I am trying to crop all images in a folder and save them in another folder. Then split all the images I have cropped using the image_slicer library.
I know a similar question like this has been asked but the difference is that I don't want the original folder to contain the cropped photos.
Here is my code so far; it runs but does nothing:
from PIL import Image
import image_slicer
import os
path = 'BeforeAfter'
arr = os.listdir(path)
def crop():
for i in arr:
if os.path.isfile(i):
img = Image.open(i)
f, e = os.path.splitext(i)
left = 66.6
top = 37.4
right = 1212.4
bottom = 550.7
imCrop = img.crop((left, top, right, bottom))
imCrop.save("CroppedImages/", "PNG", quality= 100)
# tiles = image_slicer.slice(toslice, 12, save=False)
# image_slicer.save_tiles(tiles, directory='frames')
crop()

Stitching multiple pngs into a h5 image h5py

I created an model in blender. From here I took 2d slices through the y-plane of that model leading to the following.
600 png files each corresponding to a ylocation i.e y=0, y=0.1 etc
Each png file has a resolution of 500 x 600.
I am now trying to merge the 600 pngs into a h5 file using python before loading the .h5 into some software. I find that each individual png file is read fine and looks great. However when I look at the final 3d image there is some stretching of the image, and im not sure how this is being created.
The images are resized (from 600x600 to 500x600, but I have checked and this is not the cause of the stretching). I would like to know why I am introducing such stretching in other planes (not y-plane).
Here is my code, please note that there is some work in progress here, hence why I append the dataset to a list (this is to be used for later code)
from PIL import Image
import sys
import os
import h5py
import numpy as np
import cv2
from datetime import datetime
dir_path = os.path.dirname(os.path.realpath(__file__))
sys.path.append(dir_path + '//..//..')
Xlen=500
Ylen=600
Zlen=600
directory=dir_path+"/LowPolyA21/"
for filename in os.listdir(directory):
if fnmatch.fnmatch(filename, '*.png'):
image = Image.open(directory+filename)
new_image = image.resize((Zlen, Xlen))
new_image.save(directory+filename)
dataset = np.zeros((Xlen, Zlen, Ylen), np.float)
# traverse all the pictures under the specified address
cnt_num = 0
img_list = sorted(os.listdir(directory))
os.chdir(directory)
for img in (img_list):
if img.endswith(".png"):
gray_img = cv2.imread(img, 0)
dataset[:, :, cnt_num] = gray_img
cnt_num += 1
dataset[dataset == 0] = -1
dataset=dataset.swapaxes(1,2)
datasetlist=[]
datasetlist.append(dataset)
dz_dy_dz = (float(0.001),float(0.001),float(0.001))
for j in range(Xlen):
for k in range(Ylen):
for l in range(Zlen):
if datasetlist[i][j,k,l]>1:
datasetlist[i][j,k,l]=1
now = datetime.now()
timestamp = now.strftime("%d%m%Y_%H%M%S%f")
out_h5_path='voxelA_'+timestamp+'_flipped'
out_h5_path2='voxelA_'+timestamp+'_flipped.h5'
with h5py.File(out_h5_path2, 'w') as f:
f.attrs['dx_dy_dz'] = dz_dy_dz
f['data'] = datasetlist[i] # Write data to the file's primary key data below
Example of image without stretching (in y-plane)
Example of image with stretching (in x-plane)

How implement an array of images in Python-opencv?

I am programming a code that uses 30 images and I want to put those images in an array to resize them and then use them in other functions. I was trying some things but the second loop just shows me one unique image resized 30 times.
import cv2 as cv
import glob
import numpy as np
files = glob.glob ("C:/Users/Project/imgs/*.jpg")
images = np.empty(len(files))
#This loop reads images and show rgb images
#Works OK
for i in files:
#print(myFile)
images= cv.imread(i)
cv.imshow('myFile'+str(i),images)
new = []
for i in range(30):
new = cv.resize(images,(200,266))
cv.imshow('imagen', new)
cv.waitKey(0)
cv.destroyAllWindows()
If you want to keep many elements then first create empty list and next use apppend() to add element to list.
More or less
all_images = []
for name in files:
#print(name)
image = cv.imread(name)
cv.imshow('myFile '+name, image) # you don't need `str()`
all_images.append(image)
resized_images = []
for image in all_images:
new = cv.resize(image, (200,266))
cv.imshow('imagen', new)
resized_images.append(new)
If you want to resize only first 30 images
for image in all_images[:30]:

Categories

Resources