Modify path name when saving with PIL - python

I am extracting RGB channels from images and saving them as grayscale png files, but I have trouble saving them. Here is my code:
listing = os.listdir(path1)
for f in listing:
im = Image.open(path1 + f)
red, green, blue = im.split()
red = red.convert('LA')
green = green.convert('LA')
blue = blue.convert('LA')
red.save(path2 + f + 'r', 'png')
green.save(path2 + f + 'g', 'png')
blue.save(path2 + f + 'b','png')
Where path1 and path2 are image folder and save destinations respectively. What I want to do is to save the b&w version of color channel of img.png to
imgr.png, imgg.png, imgb.png, but what I get with this code is img.pngr, img.pngg, img.pngb. Any help would be appreciated.

You could do this as follows:
import os
listing = os.listdir(path1)
for f in listing:
im = Image.open(os.path.join(path1, f))
red, green, blue = im.split()
red = red.convert('LA')
green = green.convert('LA')
blue = blue.convert('LA')
file_name, file_ext = os.path.splitext(f)
red.save(os.path.join(path2, "{}r.png".format(file_name))
green.save(os.path.join(path2, "{}g.png".format(file_name))
blue.save(os.path.join(path2, "{}b.png".format(file_name))
I would recommend you make use of the os.path.split() and os.path.join() functions when working with paths and filenames.

You first need to split the filename from the extension.
import os
filename = path2 + f # Consider using os.path.join(path2, f) instead
root, ext = os.path.splitext(filename)
Then you can combine them correctly again doing:
filename = root + "r" + ext
Now filename would be imgr.png instead of img.pngr.

Related

Python/PIL Resize all images in all subfolder and save as new file name

I am going to resize image file which located in Desktop with set of subfolder.
I try following command and it works without rename save new.
from PIL import Image
import os, sys
import glob
root_dir='./././Desktop/python/'
def resize():
for filename in glob.iglob(root_dir + '**/*.jpg', recursive=True):
print(filename)
im = Image.open(filename)
imResize = im.resize((450,600), Image.ANTIALIAS)
imResize.save(filename , 'JPEG', quality=90)
resize()
My question is how can I add the correct command to save the renewe resized image file with append 'f + _thumbnail' + .jpg?
E.g file1 > file1_thumbnail.jpg
I tried add followings to row print(filename) but show error.
f, e = os.path.splitext(path+item)
size = im.size
ratio = float(final_size) / max(size)
new_image_size = tuple([int(x*ratio) for x in size])
im = im.resize(new_image_size, Image.ANTIALIAS)
new_im = Image.new("RGB", (final_size, final_size))
new_im.paste(im, ((final_size-new_image_size[0])//2, (final_size-new_image_size[1])//2))
new_im.save(f + 'resized.jpg', 'JPEG', quality=90)
May I know how can fix it?
Many Thanks
You can use python slicing of strings for this -
You can modify your code to -
from PIL import Image
import os, sys
import glob
root_dir='./././Desktop/python/'
def resize():
for filename in glob.iglob(root_dir + '**/*.jpg', recursive=True):
print(filename)
im = Image.open(filename)
imResize = im.resize((450,600), Image.ANTIALIAS)
filename = filename[:-4] + " _thumbnail" + filename[-4:]
imResize.save(filename , 'JPEG', quality=90)
resize()
The ".jpg" can be sliced at the end.

How to save images in a folder with for loop?

First, I have an issue with saving up every resized file with the same name to the same folder? Second, while running I can't understand if m t code works properly. Please, could you check if I am doing the resizing properly?Can't find a mistake in my code:
import glob
from PIL import Image
images = glob.glob("C:/Users/marialavrovskaa/Desktop/Images/*.png")
for image in images:
with open(image,"rb") as file:
img = Image.open(file)
imgResult = img.resize((800,800), resample = Image.BILINEAR)
imgResult.save('"C:/Users/marialavrovskaa/Desktop/Images/file_%d.jpg"', 'JPEG')
print("All good")
If you want to give the images a name with a consecutive number than you've to concatenate the file name and a counter:
image_no = 1
for image in images:
# [...]
name = 'C:/Users/marialavrovskaa/Desktop/Images/file_' + str(image_no) + '.jpg'
imgResult.save(name, 'JPEG')
image_no += 1
Since the format of the images is PNG and they should be stored as JPEG, the format has to be convert from RGBA to RGB, by .convert('RGB'). Note, storing a RGBA image to 'JPGE' would cause an error:
import glob
from PIL import Image
images = glob.glob("C:/Users/marialavrovskaa/Desktop/Images/*.png")
image_no = 1
for image in images:
with open(image,"rb") as file:
img = Image.open(file)
imgResult = img.resize((800,800), resample = Image.BILINEAR).convert('RGB')
name = 'C:/Users/marialavrovskaa/Desktop/Images/file_' + str(image_no) + '.jpg'
imgResult.save(name, 'JPEG')
image_no += 1
print("All good")
By the way, if the file name should by kept and the image just should be stored to a file with a different extension, then then extension can be split form the file by .splitext:
import os
imgResult = img.resize((800,800), resample = Image.BILINEAR).convert('RGB')
name = os.path.splitext(image)[0] + '.jpg'
imgResult.save(name, 'JPEG')
If you wan to store the fiel to a different path, with a different extension, then you've to extract the fiel name from the path.
See os.path. Split the path from the file name and extension by os.path.split(path), which returns a tuple of path and name.
e.g.
>>> import os
>>> os.path.split('c:/mydir/myfile.ext')
('c:/mydir', 'myfile.ext')
The split the file name and the extension by os.path.splitext(path):
>>> os.path.splitext('myfile.ext')
('myfile', '.ext')
Applied to your code this means, where file is the path, name and extension of the source image file:
import glob
from PIL import Image
images = glob.glob("C:/Users/marialavrovskaa/Desktop/Images/*.png")
image_no = 1
for image in images:
with open(image,"rb") as file:
img = Image.open(file)
imgResult = img.resize((800,800), resample = Image.BILINEAR).convert('RGB')
image_path_and_name = os.path.split(file)
image_name_and_ext = os.path.splitext(image_path_and_name[1])
name = image_name_and_ext[0] + '.png'
file_path = os.path.join(path, name)
imgResult.save(file_path , 'JPEG')
image_no += 1
print("All good")

How can I read a sequence of images (im1, im2, ...) from a folder using opencv in Python?

I want to read images named as follow: image1, image2, image3..... imagen-1, imagen in a folder called "inputfolder". After processing, I want save them in an folder named "outputfolder" as pimage1, pimage2...... pimagen-1, pimagen.
How can I do that with python?
i tried this code:
import cv2
import os
path_to_folder = "F:\\Nouveau dossier (7)\\Fred_Nat\\RGGchs"
out_folder = "F:\\Nouveau dossier (7)\\Fred_Nat\\Nouveau dossier (2)"
f = os.listdir(path_to_folder)
for i in f:
path_to_img = path_to_folder + 'image' + str(i)+'.bmp'
img = cv2.imread(path_to_img)
cv2.imshow("d",img)
cv2.imwrite(out_path + 'imagep' + str(i), img)
You can do the following where path_to_folder is the source folder path and if you wish to save processed images to new folder, write the out_path. Otherwise, leave theout_pathsame as path_to_folder
path_to_folder = ...
out_folder = ...
f = os.listdir(path_to_folder)
for i in f:
path_to_img = path_to_folder + '/' + i
img = cv.imread(path_to_img)
... # processing
cv.imwrite(out_path + '/p' + i, img)

Converting images to csv file in python

I have converted my image into a csv file and it's like a matrix but I want it to be a single row.
How can I convert all of the images in dataset into a csv file (each image into one line).
Here's the code I've used:
from PIL import Image
import numpy as np
import os, os.path, time
format='.jpg'
myDir = "Lotus1"
def createFileList(myDir, format='.jpg'):
fileList = []
print(myDir)
for root, dirs, files in os.walk(myDir, topdown=False):
for name in files:
if name.endswith(format):
fullName = os.path.join(root, name)
fileList.append(fullName)
return fileList
fileList = createFileList(myDir)
fileFormat='.jpg'
for fileFormat in fileList:
format = '.jpg'
# get original image parameters...
width, height = fileList.size
format = fileList.format
mode = fileList.mode
# Make image Greyscale
img_grey = fileList.convert('L')
# Save Greyscale values
value = np.asarray(fileList.getdata(),dtype=np.float64).reshape((fileList.size[1],fileList.size[0]))
np.savetxt("img_pixels.csv", value, delimiter=',')
input :
http://uupload.ir/files/pto0_lotus1_1.jpg
output:http://uupload.ir/files/huwh_output.png
From your question, I think you want to know about numpy.flatten(). You want to add
value = value.flatten()
right before your np.savetxt call. It will flatten the array to only one dimension and it should then print out as a single line.
The rest of your question is unclear bit it implies you have a directory full of jpeg images and you want a way to read through them all. So first, get a file list:
def createFileList(myDir, format='.jpg'):
fileList = []
print(myDir)
for root, dirs, files in os.walk(myDir, topdown=False):
for name in files:
if name.endswith(format):
fullName = os.path.join(root, name)
fileList.append(fullName)
return fileList
The surround your code with a for fileName in fileList:
Edited to add complete example
Note that I've used csv writer and changed your float64 to ints (which should be ok as pixel data is 0-255
from PIL import Image
import numpy as np
import sys
import os
import csv
#Useful function
def createFileList(myDir, format='.jpg'):
fileList = []
print(myDir)
for root, dirs, files in os.walk(myDir, topdown=False):
for name in files:
if name.endswith(format):
fullName = os.path.join(root, name)
fileList.append(fullName)
return fileList
# load the original image
myFileList = createFileList('path/to/directory/')
for file in myFileList:
print(file)
img_file = Image.open(file)
# img_file.show()
# get original image parameters...
width, height = img_file.size
format = img_file.format
mode = img_file.mode
# Make image Greyscale
img_grey = img_file.convert('L')
#img_grey.save('result.png')
#img_grey.show()
# Save Greyscale values
value = np.asarray(img_grey.getdata(), dtype=np.int).reshape((img_grey.size[1], img_grey.size[0]))
value = value.flatten()
print(value)
with open("img_pixels.csv", 'a') as f:
writer = csv.writer(f)
writer.writerow(value)
How about you convert your images to 2D numpy arrays and then write them as txt files with .csv extensions and , as delimiters?
Maybe you could use a code like following:
np.savetxt('np.csv', image, delimiter=',')
import numpy as np
import cv2
import os
IMG_DIR = '/home/kushal/Documents/opencv_tutorials/image_reading/dataset'
for img in os.listdir(IMG_DIR):
img_array = cv2.imread(os.path.join(IMG_DIR,img), cv2.IMREAD_GRAYSCALE)
img_array = (img_array.flatten())
img_array = img_array.reshape(-1, 1).T
print(img_array)
with open('output.csv', 'ab') as f:
np.savetxt(f, img_array, delimiter=",")
import os
import pandas as pd
path = 'path-to-the-folder'
os.chdir(path)
lists = os.listdir(path)
labels = []
file_lst = []
for folder in lists:
files = os.listdir(path +"/"+folder)
for file in files:
path_file = path + "/" + folder + "/" + file
file_lst.append(path_file)
labels.append(folder)
dictP_n = {"path": file_lst,
"label_name": labels,
"label": labels}
data = pd.DataFrame(dictP_n, index = None)
data = data.sample(frac=1)
data['label'] = data['label'].replace({"class1": 0, "class2": 1 })
data.to_csv("path-to-save-location//file_name.csv", index =None)

viewing images from local path(directory) in python?

i'm trying to retrieve images from my local directory using array list but i got all images from list but i don't know how to show images from list one by one.
Please help me if anyone knows.
my.py:
import os, os.path
imgs = []
# print(imgs)
path = "C:/Users/admin/PycharmProjects/my_module/static/files"
valid_images = [".jpg",".gif",".png",".tga"]
print(valid_images)
for f in os.listdir(path):
ext = os.path.splitext(f)[1]
os.listdir(path).append(f)
# Image.show(f)
There are several options depending on your environment and visualization libraries. Check this good answer
You need to do from PIL import Image, then you could do Image.open(path + "/" + f).show(). Try this:
import os, os.path
from PIL import Image
imgs = []
path = "path/to/directory"
valid_images = [".jpg", ".gif", ".png", ".tga"]
print(valid_images)
for f in os.listdir(path):
ext = os.path.splitext(f)[1]
if ext in valid_images:
imgs.append(path + "/" + f)
img = Image.open(path + "/" + f)
img.show()
print(imgs)
I have tried and i got my expected output.
py:
import os
from PIL import Image
img=[]
path="C:/Users/admin/PycharmProjects/my_module/static/files/"
for f in os.listdir(path):
ext = os.path.splitext(f)[1]
os.listdir(path).append(f)
image = Image.open(f)
image.show()

Categories