How to delete images with the low pixel value in a folder - python

I have some problems with removing images in a folder
The followings are what I have done.
import os,glob
from PIL import Image
from skimage import io
import numpy as np
path = "/Users/Xin/Desktop/SVM-Image-Classification-master/Folder"
# Delete images with the low pixel value
for filename in os.listdir(path):
images = Image.open(os.path.join(path,filename))
print(images)
print(np.mean(images))
pirnt(os.listdir(path))
if np.mean(images) < 10:
os.listdir(path).remove(filename)
print(os.listdir(path))
I expected that the images with the low pixel value can be deleted. However, the result presented as follow, the image that I want to delete is still in the list.
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=256x256 at 0x1C19FE37F0>
9.507644653320312
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=256x256 at 0x1C198F2E10>
10.004150390625
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=256x256 at 0x1C19FE37F0>
10.897491455078125
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=256x256 at 0x1C198F2F98>
10.406112670898438
['0543_AD_axial_090_PET.jpg', '0543_AD_axial_091_PET.jpg', '0543_AD_axial_093_PET.jpg', '0543_AD_axial_092_PET.jpg']
Can anyone give me a help?
Thanks

You are just removing the filename from the temporary list created by os.listdir(path). If you want to remove the file completely from disk, you need to use os.remove.
For example:
for filename in os.listdir(path):
images = Image.open(os.path.join(path,filename))
if np.mean(images) < 10:
os.remove(os.path.join(path, filename))

Related

When i convert images to greyscale with pil it rotates them

When i convert images to greyscale with pil it rotates them.
How do i disable this?
from PIL import Image
import os
path = 'spanish_pages_photos/'
pathContents = os.listdir(path)
list = []
# get file names and append to list
for i in pathContents:
list.append(i)
list = sorted(list)
#loop through and change to grey scale
for i in list[2:]:
img = Image.open(f'spanish_pages_photos/{i}').convert('L')
img.save(f'spanish_pages_photos/{i}')
print('finished')
The EXIF data can contain an "EXIF Orientation" field. Try auto-orienting with PIL.ImageOps.exif_transpose().
See here.

Using PIL to generate gif from many png files

I'm trying to combine many png images into a gif file using this solution, but it only saves one png in the gif. What am I doing wrong? My MWE is
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt
import numpy as np
import glob
thist = 4 # total time
tstep = 0 # time step
while thist>=tstep:
x = np.linspace(0,2,100)
y = np.sin(x*(thist-tstep)) # complicated calculation
fig = plt.figure(figsize=(10,6))
ax = plt.subplot(111)
plt.plot(x,y)
plt.savefig('mytest'+str(tstep)+'.png')
tstep += 1
fp_in = "mytest*.png"
fp_out = "myimage.gif"
# https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#gif
img, *imgs = [Image.open(f) for f in sorted(glob.glob(fp_in))]
img.save(fp=fp_out, format='GIF', append_images=imgs,
save_all=True, duration=200, loop=0)
In addition,
>> print(glob.glob(fp_in))
['mytest0.png', 'mytest1.png', 'mytest2.png', 'mytest3.png', 'mytest4.png']
>> print(imgs)
[<PIL.PngImagePlugin.PngImageFile image mode=RGBA size=1000x600 at 0x7F8FCEB33240>, <PIL.PngImagePlugin.PngImageFile image mode=RGBA size=1000x600 at 0x7F8FCEB33400>, <PIL.PngImagePlugin.PngImageFile image mode=RGBA size=1000x600 at 0x7F8FCEB33470>, <PIL.PngImagePlugin.PngImageFile image mode=RGBA size=1000x600 at 0x7F8FCEBACB38>]
As others have mentioned in comments the code you posted works on the latest Python + pillow distribution. Possible issue with your pillow version, similar issue is mentioned here PIL.PngImagePlugin.PngImageFile images can't be saved as GIFs in 7.1.1.
Solution in that issue is to
update Pillow
.copy() all frames
use jpg instead of png.

Extract an image from a PDF in python

I'm trying to extract images from a pdf using PyPDF2, but when my code gets it, the image is very different from what it should actually look like, look at the example below:
But this is how it should really look like:
Here's the pdf I'm using:
https://www.hbp.com/resources/SAMPLE%20PDF.pdf
Here's my code:
pdf_filename = "SAMPLE.pdf"
pdf_file = open(pdf_filename, 'rb')
cond_scan_reader = PyPDF2.PdfFileReader(pdf_file)
page = cond_scan_reader.getPage(0)
xObject = page['/Resources']['/XObject'].getObject()
i = 0
for obj in xObject:
# print(xObject[obj])
if xObject[obj]['/Subtype'] == '/Image':
if xObject[obj]['/Filter'] == '/DCTDecode':
data = xObject[obj]._data
img = open("{}".format(i) + ".jpg", "wb")
img.write(data)
img.close()
i += 1
And since I need to keep the image in it's colour mode, I can't just convert it to RBG if it was CMYK because I need that information.
Also, I'm trying to get dpi from images I get from a pdf, is that information always stored in the image?
Thanks in advance
I used pdfreader to extract the image from your example.
The image uses ICCBased colorspace with the value of N=4 and Intent value of RelativeColorimetric. This means that the "closest" PDF colorspace is DeviceCMYK.
All you need is to convert the image to RGB and invert the colors.
Here is the code:
from pdfreader import SimplePDFViewer
import PIL.ImageOps
fd = open("SAMPLE PDF.pdf", "rb")
viewer = SimplePDFViewer(fd)
viewer.render()
img = viewer.canvas.images['Im0']
# this displays ICCBased 4 RelativeColorimetric
print(img.ColorSpace[0], img.ColorSpace[1].N, img.Intent)
pil_image = img.to_Pillow()
pil_image = pil_image.convert("RGB")
inverted = PIL.ImageOps.invert(pil_image)
inverted.save("sample.png")
Read more on PDF objects: Image (sec. 8.9.5), InlineImage (sec. 8.9.7)
Hope this works: you probably need to use another library such as Pillow:
Here is an example:
from PIL import Image
image = Image.open("path_to_image")
if image.mode == 'CMYK':
image = image.convert('RGB')
image.write("path_to_image.jpg")
Reference: Convert from CMYK to RGB

Want to append colored images to a list and convert that list to grayscale using OpenCV

So basically I'm trying to convert a set of RGB images to grayscale using cv2.cvtColor and python is throwing the following error:
Traceback (most recent call last):
File "MCG.py", line 53, in
gray = cv2.cvtColor(data, cv2.COLOR_BGR2GRAY)
TypeError: src is not a numpy array, neither a scalar.
This here is the code:
import numpy as np
import cv2
import dlib
import sys
import skimage
from PIL import Image
import os
import glob
folderpath = sys.argv[1]
cascPath = sys.argv[2]
imageformat = ".tif"
path = folderpath
imfilelist = [os.path.join(path,f) for f in os.listdir(path) if f.endswith(imageformat)]
data = []
for IMG in imfilelist:
print IMG
image = cv2.imread(IMG)
data.append(image)
cv2.imshow('Image', image)
cv2.waitKey(0)
faceCascade = cv2.CascadeClassifier(cascPath)
predictor = dlib.shape_predictor(PREDICTOR_PATH)
gray = cv2.cvtColor(data, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.05,
minNeighbors=5,
minSize=(100,100)
)
As you can see, I'm trying to append all these images to a list, which will then be converted using the cv2.cvtColor function. However, that error is thrown. What am I doing wrong? Thank you.
P.S if anyone is wondering why I imported modules that don't seem to be used in this code, this code is just a segment of the whole thing and all of those modules have are being utilized in one way or the other.
If you read the cv2.cvtColor documentation, you can see that the first parameter is the Src 8-bit single channel image. However, in your case you are giving an entire list of images.
So change the code as
gray = []
for j in range(0,len(data)):
gray.append(cv2.cvtColor(np.array(data[j]), cv2.COLOR_BGR2GRAY))
I guess this should work.
You are collecting the images into a list with
data = []
for IMG in imfilelist:
...
data.append(image)
....
and then trying to convert the list with
gray = cv2.cvtColor(data, cv2.COLOR_BGR2GRAY)
This is why you are getting the error - the error is telling you that data is not an image (numpy array) but is a list. You need to convert one image at a time with cv2.cvtColor().
You could try
gray = []
for img in data:
gray.append(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY))
This would give you a list of greyscaled images, which is what I think you want to do.

Feature selection using python

It's a letter recognition task and there are 284 images, and 19 classes. I want to apply naive bayesian. First I have to convert each image to feature vector and for reducing extra info I should use some feature selection code like cropping images to remove extra black borders. But I'm not much experienced in python.
How can I crop black spaces in images in order to decrease the size of csv files? ( because the columns are more than expected!) And also how can I resize images to be the same size?
from PIL import Image, ImageChops
from resize import trim
import numpy as np
import cv2
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('image_ocr')
#print(myFileList)
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')
# 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("trainData.csv", 'a') as f:
writer = csv.writer(f)
writer.writerow(value)

Categories