How to add (merge) multiple images in one directory - python

I have two types (A and B) of images in one directory and I want to add them together (not concatenate) them like this:
A1.jpeg + B1.jpeg = Merged1.jpeg
A2.jpeg + B2.jpeg = Merged2.jpeg
      ...
AN.jpeg + BN.jpeg = MergedN.jpeg
I don't know how to customize my code so it would work for the whole directory:
import cv2
import os
for i,filenames in os.walk('.'):
A1 = cv2.imread('A1.jpeg',0)
B1 = cv2.imread('B1.jpeg',0)
image = cv2.add([A1,B1])
filename = ('Merged' + {i} + '.jpeg')
cv2.imwrite(filename, image)
Any ideas? Thanks
EDIT:
I added counter in for loop, because you cannot define for loop in the way I did before.
import cv2
import os
i=0
for filenames in os.walk('.'):
i = i + 1
A = "A" + str(i) + ".jpeg"
B = "B" + str(i) + ".jpeg"
Ai = cv2.imread(A,0)
Bi = cv2.imread(B,0)
image = cv2.add([Ai,Bi])
filename = ('Merged' + str(i) + '.jpeg')
cv2.imwrite(filename, image)
But it only adds A1 and B1. Is this a wrong way to count in for loop?

Just change the filename in imread with a custom variable which you can use i in.
A = "A" + str(i) + ".jpeg"
B = "B" + str(i) + ".jpeg"
Ai = cv2.imread(A,0)
Bi = cv2.imread(B,0)
I assumed that i is a number.

You can use glob for that it will be easier i think
import glob
for i, a_file in enumerate(glob.glob('./A*')):
A = cv2.imread(a_file,0)
B = cv2.imread(a_file.replace('A', 'B'),0)
image = cv2.add([A,B])
filename = ('Merged' + {i} + '.jpeg')
cv2.imwrite(filename, image)

I solved it like this:
import glob
import cv2
number_of_images = 750
for a_file in glob.glob('./A*'):
for i in range(1,number_of_images):
A = "A" + str(i) + ".jpeg"
B = "B" + str(i) + ".jpeg"
A1 = cv2.imread(A,0)
B1 = cv2.imread(B,0)
image = cv2.add([A1,B1])
filename = ('Merged' + str(i) + '.jpeg')
cv2.imwrite(filename, image)
print(i)
if i==number_of_images-1:
break
Thanks for your advices!

Related

How to move files using Regex or String Formatting in Python

I am a beginner in the field of Data Science and I am working with Data Preprocessing in python. However, I am working with the Fingers Dataset so I want to move the pictures so every pic fits in its own directory to be able to use ImageDataGenerator and flowfromdirectory to import the pictures and apply rescaling, flipping... etc
the code below shows what I'm trying to do...
dataset_path = "/tmp/extracted_fingers/fingers"
train_set = os.path.join(dataset_path, "train/")
test_set = os.path.join(dataset_path, "test/")
for i in range(6):
os.mkdir("/tmp/extracted_fingers/fingers/train/" + str(i) + "L")
os.mkdir("/tmp/extracted_fingers/fingers/test/" + str(i) + "L")
for i in range(6):
os.mkdir("/tmp/extracted_fingers/fingers/train/" + str(i) + "R")
os.mkdir("/tmp/extracted_fingers/fingers/test/" + str(i) + "R")
L_0_tr = glob.glob(train_set + "*0L.png")
L_1_tr = glob.glob(train_set + "*1L.png")
L_2_tr = glob.glob(train_set + "*2L.png")
L_3_tr = glob.glob(train_set + "*3L.png")
L_4_tr = glob.glob(train_set + "*4L.png")
L_5_tr = glob.glob(train_set + "*5L.png")
R_0_tr = glob.glob(train_set + "*0R.png")
R_1_tr = glob.glob(train_set + "*1R.png")
R_2_tr = glob.glob(train_set + "*2R.png")
R_3_tr = glob.glob(train_set + "*3R.png")
R_4_tr = glob.glob(train_set + "*4R.png")
R_5_tr = glob.glob(train_set + "*5R.png")
L_0_ts = glob.glob(test_set + "*0L.png")
L_1_ts = glob.glob(test_set + "*1L.png")
L_2_ts = glob.glob(test_set + "*2L.png")
L_3_ts = glob.glob(test_set + "*3L.png")
L_4_ts = glob.glob(test_set + "*4L.png")
L_5_ts = glob.glob(test_set + "*5L.png")
R_0_ts = glob.glob(test_set + "*0R.png")
R_1_ts = glob.glob(test_set + "*1R.png")
R_2_ts = glob.glob(test_set + "*2R.png")
R_3_ts = glob.glob(test_set + "*3R.png")
R_4_ts = glob.glob(test_set + "*4R.png")
R_5_ts = glob.glob(test_set + "*5R.png")
shutil.move(L_0_tr, "0L")
shutil.move(L_1_tr, "1L")
shutil.move(L_2_tr, "2L")
shutil.move(L_3_tr, "3L")
shutil.move(L_4_tr, "4L")
shutil.move(L_5_tr, "5L")
shutil.move(R_0_tr, "0R")
shutil.move(R_1_tr, "1R")
shutil.move(R_2_tr, "2R")
shutil.move(R_3_tr, "3R")
shutil.move(R_4_tr, "4R")
shutil.move(R_5_tr, "5R")
shutil.move(L_0_ts, "0L")
shutil.move(L_1_ts, "1L")
shutil.move(L_2_ts, "2L")
shutil.move(L_3_ts, "3L")
shutil.move(L_4_ts, "4L")
shutil.move(L_5_ts, "5L")
shutil.move(R_0_ts, "0R")
shutil.move(R_1_ts, "1R")
shutil.move(R_2_ts, "2R")
shutil.move(R_3_ts, "3R")
shutil.move(R_4_ts, "4R")
shutil.move(R_5_ts, "5R")
Now this way can do the job, but I am 100% sure there are better ways with much less typing to do it, so I, as a beginner, am trying to do it...
I do not know whether it can be done by loops, Regex, and string formatting or any other way...
However, if anyone could help me, I will be appreciated...
A little help can be good.
Thanks in advance.
Much Love
Note: if you want I can give more information
I don't know if it'll help much, but you can use the map built-in function to reduce a few lines.
map(lambda x: shutil.move(glob.glob(train_set + "*"+str(x)+"R.png"),str(x)+"R"), range(0,6))
map(lambda x: shutil.move(glob.glob(train_set + "*"+str(x)+"L.png"),str(x)+"L"), range(0,6))
map(lambda x: shutil.move(glob.glob(test_set + "*"+str(x)+"R.png"),str(x)+"R"), range(0,6))
map(lambda x: shutil.move(glob.glob(test_set + "*"+str(x)+"L.png"),str(x)+"L"), range(0,6))
I found my own way of doing it, however, I will share the code in case of someone need it...
def moving_pics(files_set):
for i in range(0, 6):
direction = glob.glob(files_set + "*" + str(i) + "L.png")
for p in direction:
shutil.move(p, files_set + str(i) + "L")
for i in range(0, 6):
sec_direction = glob.glob(files_set + "*" + str(i) + "R.png")
for p2 in sec_direction:
shutil.move(p2, files_set + str(i) + "R")
then you pass the path to the function parameter
**Note: **you need to pass the path as it ends with "/".

Python Permission Error [WinError32]...being used by another process

I have some images in a folder and if their dimensions are not what I want, I copy them to another folder and then resize them using the thumbnail command. After I've done that I want to rename them and as part of their new name I want to include the pixel sizes.
Anyway I've tried my code and I run into the following error:
File "C:/Anaconda/PhD/Scikit-Learn/Image Resizing3.py", line 55, in resize_img
os.rename(image_directory + '/Resized'+ "/" + image_filenames[i],image_directory + '/Resized'+ "/" + image_filenames[i][0:(len(image_filenames[i])-4)]+ str(img1.size[0]) + ' x ' + str(img1.size[1]) + '.jpg' )
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process:
I thought if I used the with keyword that it would close any processes I was using.
If anyone can see any problems in my code wrt to the error then I'd really appreciate it if you have a solution for it.
import scipy.io as sio
from matplotlib import pyplot as plt
from matplotlib import image as mpimg
from PIL import Image
from collections import OrderedDict
import shutil as sh
import os
image_directory = 'C:/StreetView/Labelled Images with Classes/Folder1 /Labelled/Classes/wood'
def resize_img(image_directory, pixel_width, pixel_height):
image_filenames = []
DIR = os.listdir(image_directory)
for n in DIR:
if n.endswith('.jpg'):
image_filenames.append(n)
image_sizes = []
images = []
for i in range(len(image_filenames)):
with Image.open(image_directory + '/' + image_filenames[i]) as images:
image_sizes.append(tuple(images.size))
ordered_imsize = tuple(OrderedDict.fromkeys(image_sizes))
pixarea = []
for i in range(len(ordered_imsize)):
arg1 = ordered_imsize[i][0]
arg2 = ordered_imsize[i][1]
pixarea.append(arg1 * arg2)
print('The maximum pixel area is', max(pixarea))
print('The image dimensions giving the largest area is:', ordered_imsize[pixarea.index(max(pixarea))] )
print('The minimum pixel area is', min(pixarea))
print('The image dimensions giving the smallest area is:', ordered_imsize[pixarea.index(min(pixarea))] )
if not os.path.exists(image_directory + '/Resized'):
os.mkdir(image_directory + '/Resized') # Then make the folder
for i in range(len(image_directory)):
if (image_sizes[i][0] >= 100) or (image_sizes[i][1] >= 400):
print('Inside the greater than loop')
sh.copy(image_directory + "/" + image_filenames[i],image_directory + '/Resized')
image_sizes1 = []
with Image.open(image_directory + '/Resized'+ "/" + image_filenames[i]) as img1: # need to use the with keyword because this makes sure the file is closed after its been used so it doesn't cause any conflicts like it did when it wasn't used.
print('Checking size: ', img1.size)
img2 = img1.thumbnail((pixel_width,pixel_height)) # img1 is not the thumbnail
image_sizes1.append(tuple(img1.size))
os.rename(image_directory + '/Resized'+ "/" + image_filenames[i],image_directory + '/Resized'+ "/" + image_filenames[i][0:(len(image_filenames[i])-4)]+ str(img1.size[0]) + ' x ' + str(img1.size[1]) + '.jpg' )
print('Image number', i, 'has been resized')
else:
print('inside the else loop')
sh.copy(image_directory + "/" + image_filenames[i],image_directory + '/Resized')
image_sizes2 = []
with Image.open(image_directory + '/Resized'+ "/" + image_filenames[i]) as img3:
image_sizes2.append(tuple(img3.size))
img3.save(image_directory + '/Resized' + "/" + image_filenames[i][0:len(image_filenames[i])-4] + '_' + str(img3.size[0]) + 'x' + str(img3.size[1]) + ".jpg")
#os.remove(image_directory + '/Resized'+ "/" + image_filenames[i])
print('Image number', i, 'has been copied over and not resized')
resize_img(image_directory,100,400)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process
Solved it, I used shutil.move instead of os.rename.

xml libxml2 parsing

In the code below, my problem is that it's writing output to all folders based on only one input file. Can some one give me a hint and check if my code is looping properly?
import libxml2
import os.path
from numpy import *
from cfs_utils import *
np=[1,2,3,4,5,6,7,8]
n=[20,30,40,60,80,100,130]
solver=["CG_iluk", "CG_saamg", "CG_ssor", "BiCGSTABL_iluk", "BiCGSTABL_saamg", "BiCGSTABL_ssor", "cholmod", "ilu" ]
file_list=["eval_CG_iluk_default","eval_CG_saamg_default", "eval_CG_ssor_default", "eval_BiCGSTABL_iluk", "eval_BiCGSTABL_saamg", "eval_BiCGSTABL_ssor","simp_cholmod_solver_3D_evaluate ", "simp_ilu_solver_3D_evaluate" ]
for sol in solver:
i=0
for cnt_np in np:
#open write_file= "Graphs/" + "Np"+ cnt_np + "/CG_iluk.dat"
#"Graphs/Np1/CG_iluk.dat"
write_file = open("Graphs/"+ "Np"+ str(cnt_np) + "/" + sol + ".dat", "w")
#loop through different unknowns
for cnt_n in n:
#open file "cfs_calculations_" + cnt_n +"np"+ cnt_np+ "/" + file_list(i) + "_default.info.xml"
read_file = "cfs_calculations_" +str(cnt_n) +"np"+ str(cnt_np) + "/" + file_list[i] + ".info.xml"
#read wall and cpu time and write
if os.path.exists(read_file):
doc = libxml2.parseFile(read_file)
xml = doc.xpathNewContext()
walltime = xpath(xml, "//cfsInfo/sequenceStep/OLAS/mechanic/solver/summary/setup/timer/#wall")
cputime = xpath(xml, "//cfsInfo/sequenceStep/OLAS/mechanic/solver/summary/setup/timer/#cpu")
unknowns = 3*cnt_n*cnt_n*cnt_n
write_file.write(str(unknowns) + "\t" + walltime + "\t" + cputime + "\n")
doc.freeDoc()
write_file.close()
i=i+1
Problem solved, I = o, was outside the loop

Python PIL - Resizing Images Without Keeping Aspect Ratio

So I've got a Python script that takes a bunch of images in a folder, and puts them together into arrays (like this). I also have another script that takes the frames of a video and puts them together in arrays. The problem is, the one that takes the frames from a video creates black bars between the images.
Here is the correct image made using the first script, which uses JPEGS:
Here is the wrong image made using the second script, which uses video frames:
Here is the script that makes the correct first image:
import Image
import glob
import os
name = raw_input('What is the file name (excluding the extension) of your video that was converted using FreeVideoToJPGConverter?\n')
x_res = int(raw_input('What do you want the width of your image to be (in pixels)?\n'))
y_res = int(raw_input('What do you want the height of your image to be (in pixels)?\n'))
rows = int(raw_input('How many rows do you want?\n'))
columns = int(raw_input('How many columns do you want?\n'))
images = glob.glob('./' + name + ' (*)/' + name + '*.jpg')
new_im = Image.new('RGB', (x_res,y_res))
x_cntr = 0
y_cntr = 0
if not os.path.exists('./' + name + ' Output/'):
os.makedirs('./' + name + ' Output/')
for x in xrange(0,len(images),1):
if x%(rows*columns) == 0:
new_im.save('./' + name + ' Output/' + str(x) + '.jpg')
new_im = Image.new('RGB', (x_res,y_res))
y_cntr = 0
x_cntr = 0
print str(round(100*(float(x)/len(images)), 1)) + "% Complete"
elif x%rows == 0:
x_cntr = 0
y_cntr = y_cntr + y_res/columns
elif x%1 == 0:
x_cntr = x_cntr + x_res/rows
im = Image.open(images[x])
im = im.resize((x_res/rows + x_res%rows, y_res/columns + y_res%columns), Image.ANTIALIAS)
new_im.paste(im, (x_cntr, y_cntr))
Here is the script that makes the incorrect second image:
import cv2, Image, os
name = raw_input('Video File (With Extension): ')
x_res = int(raw_input('Image Width (Pixels): '))
y_res = int(raw_input('Image Height (Pixels): '))
rows = int(raw_input('Number of Rows: '))
columns = int(raw_input('Number of Columns: '))
vidcap = cv2.VideoCapture(name)
success,im = vidcap.read()
frames = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT))
new_im = Image.new('RGB', (x_res, y_res))
x_cntr = 0
y_cntr = 0
print str(frames) + " Frames to Join"
if not os.path.exists('./' + name + ' Output/'):
os.makedirs('./' + name + ' Output/')
for x in xrange(0,frames,1):
if x%(rows*columns) == 0:
new_im.save('./' + name + ' Output/' + str(x) + '.jpg')
new_im = Image.new('RGB', (x_res,y_res))
y_cntr = 0
x_cntr = 0
print str(round(100*(float(x)/frames), 1)) + "% Complete"
elif x%rows == 0:
x_cntr = 0
y_cntr = y_cntr + y_res/columns
elif x%1 == 0:
x_cntr = x_cntr + x_res/rows
success,cv2_im = vidcap.read()
if success == True:
cv2_im = cv2.cvtColor(cv2_im,cv2.COLOR_BGR2RGB)
im = Image.fromarray(cv2_im)
im = im.resize((x_res/rows + x_res%rows, y_res/columns + y_res%columns), Image.ANTIALIAS)
new_im.paste(im, (x_cntr, y_cntr))
elif success == False:
new_im.save('./' + name + ' Output/' + str(x) + '.jpg')
print str(round(100*(float(x)/frames), 1)) + "% Complete" #Why isn't this 100%, fix
As you can see, this specific line for resizing the image (to fit the new array of images) is exactly the same in both scripts:
im = im.resize((x_res/rows + x_res%rows, y_res/columns + y_res%columns), Image.ANTIALIAS)
...Except in the first script, the image is opened from a JPEG, and in the second script, the image is taken from a video frame using OpenCV2. If I try this with a different video, the same thing happens. It resizes as if I were using .thumbnail instead of .resize.
So why is there a different output even though they are the same script?
PS: I also don't know why there are more output images on the jpeg script than the video script, but that may be the fault of FreeVideoToJPGConverter (a software); I'm not sure though.

Script Loop through files in directory

I have the following code which creates the txt file I require from a shp.file with the data I need. I have a folder called profiles containing a few number of shape files named (profil1.shp, profil2.shp, profil3.shp etc.). I was wondering how to create a loop so that the script creates for each file a txt file with the same name (eg. for profil1.shp create profil1.txt, profil2.shp create profil2.txt and so on).
import ogr, os, sys, osr
os.chdir('..\profiles')
file = open('profil1.txt', 'w')
driver = ogr.GetDriverByName('ESRI Shapefile')
datasource = driver.Open('profil1.shp', 0)
if datasource is None:
print 'Could not open file'
sys.exit(1)
layer = datasource.GetLayer()
feature = layer.GetNextFeature()
while feature:
id = feature.GetFieldAsString('ID')
Distanta = feature.GetFieldAsString('DIST')
Z = feature.GetFieldAsString('Z')
geom = feature.GetGeometryRef()
x = str(geom.GetX())
y = str(geom.GetY())
file.write(id + " " + Distanta + " " + "[X]:" + " " + x + ' ' + '[Y]:' + " " + y + " " + " " + "[Z]" + Z + " " + "\n")
feature.Destroy()
feature = layer.GetNextFeature()
datasource.Destroy()
file.close()
edit: the code is returning a Could not open file.Photo of the folder containing the files and their respective names. Safe to assume I am doing something wrong.
import ogr, os, sys, osr,os.path
os.chdir = ('C:\Users\Andrei\Desktop\profil3')
l = os.listdir('C:\Users\Andrei\Desktop\profil3')
for i in l:
if i.endswith('.shp'):
s1 = s.split('.')[0] + '.txt'
file = open(s1, 'w')
driver = ogr.GetDriverByName('ESRI Shapefile')
datasource = driver.Open(i, 0)
if datasource is None:
print 'Could not open file'
sys.exit(1)
layer = datasource.GetLayer()
feature = layer.GetNextFeature()
while feature:
id = feature.GetFieldAsString('ID')
Distanta = feature.GetFieldAsString('DIST')
Z = feature.GetFieldAsString('Z')
geom = feature.GetGeometryRef()
x = str(geom.GetX())
y = str(geom.GetY())
file.write(id + " " + Distanta + " " + "[X]:" + " " + x + ' ' + '[Y]:' + " " + y + " " + " " + "[Z]" + Z + " " + "\n")
feature.Destroy()
feature = layer.GetNextFeature()
datasource.Destroy()
file.close()
You can use os.listdir() to list the files and folders in the current directory.
This returns a list of all files in the current directory (or the directory given to it as parameter , if no parameter is specified it checks the current directory) .
Then you can check for files with the name ending with .shp using string.endswith() function and then use that to create your new files.
Example of a small portion -
import os , os.path
l = os.listdir()
for i in l:
if i.endswith('.shp'):
s1 = s.split('.')[0] + '.txt'
At the end s1 would contain the file with extension as .txt .
Then you can do your logic on this file, and keep on doing like this.
Full code would look something like -
import ogr, os, sys, osr,os.path
os.chdir('..\profiles')
l = os.listdir()
for i in l:
if i.endswith('.shp'):
s1 = s.split('.')[0] + '.txt'
file = open(s1, 'w')
driver = ogr.GetDriverByName('ESRI Shapefile')
datasource = driver.Open(i, 0)
if datasource is None:
print 'Could not open file'
sys.exit(1)
layer = datasource.GetLayer()
feature = layer.GetNextFeature()
while feature:
id = feature.GetFieldAsString('ID')
Distanta = feature.GetFieldAsString('DIST')
Z = feature.GetFieldAsString('Z')
geom = feature.GetGeometryRef()
x = str(geom.GetX())
y = str(geom.GetY())
file.write(id + " " + Distanta + " " + "[X]:" + " " + x + ' ' + '[Y]:' + " " + y + " " + " " + "[Z]" + Z + " " + "\n")
feature.Destroy()
feature = layer.GetNextFeature()
datasource.Destroy()
file.close()
A better way of openning files, etc is using with statement. Look up its tutorial here.

Categories

Resources