Python Image.open() does not recognize regular expression - python

from PIL import Image
image1 = "Image_I0000_F1_Filter 1_1A_health_2014-05-20_11.05.33.483.tiff"
image2 = "*F1*.tiff"
im1 = Image.open(image1)
im2 = Image.open(image2)
Tried to open the same image. im1 opens with no problem, but im2 shows IOError: [Errno 2] No such file or directory: '*F1*.tiff'.
Also tried
image2 = r"*F1*.tiff"
im2 = Image.open(image2)
and
image2 = "*F1*.tiff"
im2 = Image.open(open(image2,'rb'))
neither works.

PIL.Image.open has no glob matching. The documentation advises
You can use either a string (representing the filename) or a file object as the file argument
Notably not including glob matching.
Python uses the glob module to do glob matching.
from PIL import Image
import glob
filenames = glob.glob("*F1*.tiff")
# gives a list of matches, in this case most likely
# # ["Image_I0000_F1_Filter 1_1A_health_2014-05-20_11.05.33.483.tiff"]
if filenames:
filename = filenames[0]
else:
# what do we do if there's no such file? I guess pass the empty string
# to Image and let it deal with it
filename = ""
# or maybe directly...
raise FileNotFoundError
im1 = Image.open(filename)

Related

removing images with specific size using python

i have a folder with lots of jpg images. and i need to delete all the pictures which have size les than 160*160.i tried couple of codes in python my self. but they didn't work and i don't know what to do about it.
import os
from PIL import Image
folder_images = "dataset/PetImages/Cat"
for filenames in os.walk(folder_images):
img = Image.open(filenames)
h, w = img.shape
if(not (h >= 160 or w >= 160)):
os.remove(img)
here is the error i get:
fp = io.BytesIO(fp.read())
AttributeError: 'tuple' object has no attribute 'read'
Your mistake is that Image.open() returns an Image object, but os.remove() needs the path of file, not an Image object.
So here img should be replaced by filenames or something indicating the path of image.
Maybe you should read the documents carefully:
https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.open
https://docs.python.org/3/library/os.html#os.remove
By the way, an PIL.image object do not has shape attribute, what you need is size.
You're trying to open a list of images instead of just 1 image. Moreover, os.remove(img) is not correct since img is a PIL.image object instead of a filepath as #Sinon has mentioned already. Try this instead:
import os
from PIL import Image
folder_images = "dataset/PetImages/Cat"
for _, _, image_filenames in os.walk(folder_images):
for image_filename in image_filenames:
img = Image.open(image_filename)
h, w = img.size
if(not (h >= 160 or w >= 160)):
os.remove(image_filename)

OpenCV does not accept ndarray to TextDecectorCNN.detect()

I am trying to use this OpenCV class of text detector to find out if I can use it for my project. I am loaging image like this:
src = cv2.imread(img_path)
And then I am trying to use function mentioned before like this:
bbox, confidence = cv2.text_TextDetectorCNN.detect(src)
But this code falls with the following mistake:
TypeError: descriptor 'detect' for 'cv2.text_TextDetectorCNN' objects doesn't apply to a 'numpy.ndarray' object
I have already tried to use image = cv2.cvtColor(src, cv2.COLOR_BGR2RGB, cv2.CV_8UC3) but it doesn't do a thing - image remains an ndarray.
UPD: Attaching whole code and problematic picture.
import os
# borrowed from https://github.com/lengstrom/fast-style-transfer/blob/master/src/utils.py
def list_images(in_path, formats=[".jpg", ".jpeg", ".gif", ".png", ".pgm", ".bmp"]):
img_files = []
for (dirpath, _, filenames) in os.walk(in_path):
for file in filenames:
_, ext = os.path.splitext(file)
ext = str.lower(ext)
if ext in formats:
img_files.append(os.path.join(dirpath, file))
return img_files
def test_accuracy(folder_path):
image_list = list_images(folder_path)
for img_path in image_list:
src = cv2.imread(img_path)
bbox, confidence = cv2.text_TextDetectorCNN.detect(src)
print(img_path, bbox, confidence) # To check format of output
Tested image:
(I've tested 3 different .jpg images, none of them worked)
Question: is there a way to convert ndarray into some OpenCV format that will be accepted by mentioned function?
Your problem is that you don't create an instance of your text detector. See this:
import cv2
import numpy as np
# After downloading the caffemodel and
# textbox.prototxt you have to create
# an instance of your model
textSpotter = cv2.text.TextDetectorCNN_create(
"textbox.prototxt", "TextBoxes_icdar13.caffemodel"
)
src = cv2.imread("1.png")
bbox, confidence = textSpotter.detect(src)
print("HELLO", bbox, confidence) # To check format of output

Convert image files to a csv file

I'm working on a The Japanese Female Facial Expression (JAFFE) Database. You can find the database on this link http://www.kasrl.org/jaffe.html.
When I download the database I got a list of pictures. I would like to convert these image files into a CSV file but I'm still new in deep learning and I don't know how. Someone proposed that I work with OpenCV. what should I do?
i have simple example
i hope this help you.
from PIL import Image
import numpy as np
import sys
import os
import csv
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 fileList:
print(file)
img_file = Image.open(file)
# 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')
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)
Install pillow, numpy, pandas
Convert the image to RGB
plot RGB along with x,y co-ordinates in a pandas Dataframe
Save the dataframe as csv
Sample working code as below
from PIL import Image
from numpy import array, moveaxis, indices, dstack
from pandas import DataFrame
image = Image.open("data.tiff")
pixels = image.convert("RGB")
rgbArray = array(pixels.getdata()).reshape(image.size + (3,))
indicesArray = moveaxis(indices(image.size), 0, 2)
allArray = dstack((indicesArray, rgbArray)).reshape((-1, 5))
df = DataFrame(allArray, columns=["y", "x", "red","green","blue"])
print(df.head())
df.to_csv("data.csv",index=False)
You don't need to write any code, you can just use vips on the command-line on macOS, Linux or Windows.
So, in Terminal (or Command Prompt, if on Windows):
vips im_vips2csv TM.AN1.190.tiff result.csv
will convert the 256x256 greyscale image TM.AN1.190.tiff into a 256 line CSV with 256 entries per line. Simples!
If you want to replace the tab separators by commas, you can do:
tr '\t' , < result.csv > NewFile.csv

Opening an Image from a specific file?

import glob
import numpy as np
from PIL import Image
filename = glob.glob('/home/ns3/PycharmProjects/untitled1/stego.pgm')
im= Image.open(filename)
(x,y) = im.size
I = np.array(im.getdata()).reshape(y, x)
Keeps giving me this error:
im= Image.open(filename)
File "/home/ns3/.local/lib/python2.7/site-packages/PIL/Image.py", line 2416, in open
fp = io.BytesIO(fp.read())
AttributeError: 'list' object has no attribute 'read
How can I open an image from that specific path and use the image as array I?
The issue is that glob.glob() returns a list (a possibly-empty list of path names that match pathname) and you want a string.
so either insert a [0]
import glob
import numpy as np
from PIL import Image
filenames = glob.glob('/home/ns3/PycharmProjects/untitled1/stego.pgm')
filename = filenames[0]
im= Image.open(filename)
(x,y) = im.size
I = np.array(im.getdata()).reshape(y, x)
or skip glob all together
import numpy as np
from PIL import Image
filename = '/home/ns3/PycharmProjects/untitled1/stego.pgm'
im= Image.open(filename)
(x,y) = im.size
I = np.array(im.getdata()).reshape(y, x)

How to complete this python function to save in the same folder?

I am trying to write my first real python function that does something real. What i want to accomplish is searching a given folder, and then open all images and merging them together so they make a filmstrip image. Imagine 5 images stacked on top of eachother in one image.
I have this code now, which should be pretty much ok, but propably needs some modification:
import os
import Image
def filmstripOfImages():
imgpath = '/path/here/'
files = glob.glob(imgpath + '*.jpg')
imgwidth = files[0].size[0]
imgheight = files[0].size[1]
totalheight = imgheight * len(files)
filename = 'filmstrip.jpg'
filmstrip_url = imgpath + filename
# Create the new image. The background doesn't have to be white
white = (255,255,255)
filmtripimage = Image.new('RGB',(imgwidth, totalheight),white)
row = 0
for file in files:
img = Image.open(file)
left = 0
right = left + imgwidth
upper = row*imgheight
lower = upper + imgheight
box = (left,upper,right,lower)
row += 1
filmstripimage.paste(img, box)
try:
filmstripimage.save(filename, 'jpg', quality=90, optimize=1)
except:
filmstripimage.save(miniature_filename, 'jpg', quality=90)")
How do i modify this so that it saves the new filmstrip.jpg in the same directory as I loaded the images from? And it probably has some things that are missing or wrong, anybody got a clue?
Related question: How to generate a filmstrip image in python from a folder of images?
It is not an answer to your question, but It might be helpful:
#!/usr/bin/env python
from PIL import Image
def makefilmstrip(images, mode='RGB', color='white'):
"""Return a combined (filmstripped, each on top of the other) image of the images.
"""
width = max(img.size[0] for img in images)
height = sum(img.size[1] for img in images)
image = Image.new(mode, (width, height), color)
left, upper = 0, 0
for img in images:
image.paste(img, (left, upper))
upper += img.size[1]
return image
if __name__=='__main__':
# Here's how it could be used:
from glob import glob
from optparse import OptionParser
# process command-line args
parser = OptionParser()
parser.add_option("-o", "--output", dest="file",
help="write combined image to OUTPUT")
options, filepatterns = parser.parse_args()
outfilename = options.file
filenames = []
for files in map(glob, filepatterns):
if files:
filenames += files
# construct image
images = map(Image.open, filenames)
img = makefilmstrip(images)
img.save(outfilename)
Example:
$ python filmstrip.py -o output.jpg *.jpg
I think if you change your try section to this:
filmstripimage.save(filmstrip_url, 'jpg', quality=90, optimize=1)
In the case you are not joking there are several problems with your script e.g. glob.glob() returns list of filenames (string objects, not Image objects) therefore files[0].size[0] will not work.
as J. F. Sebastian mentioned, glob does not return image objects... but also:
As it is right now, the script assumes the images in the folder are all the same size and shape. This is not often a safe assumption to make.
So for both of those reasons, you'll need to open the images before you can determine their size. Once you open it you should set the width, and scale the images to that width so there is no empty space.
Also, you didn't set miniature_filename anywhere in the script.

Categories

Resources