Using PIL to generate gif from many png files - python

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.

Related

Using Tesseract-OCR in Python to get number from images

I have thousands of scale images that I would like to extract the reading of the scale from each image. However, when using the Tesseract it gives wrong values. I tried several process for the image but still running to same issue. From my understanding so far after defining region of interest in the image, it has to be converted to white text with black background. However, I am new to python, I tried some functions to do so but still running to same issue. Would be appreciated if someone can help me on this one. The following link is for the image, as I couldn't uploaded it here as it is more than 2 MiB:
https://mega.nz/file/fZMUDRbL#tg4Tc2VmGMMdEpnZzt7blxZjVLdlhMci9jll0FLnIGI
import cv2
import pytesseract
import matplotlib.pyplot as plt
import numpy as np
import imutils
## Reading Image File
Filename = 'C:\\Users\\Abdullah\\Desktop\\Scale Reading\\' #File Path For Images
IName = 'Disk_Test_1_09_07-00000_0.tif' # Image Name
Image = cv2.imread(Filename + IName,0)
## Image Processing
Image_Crop = Image[1680:1890, 550:1240] # Define Region of Interest of the image
#cv2.imshow("cropped", Image_Crop) # Show Cropped Image
#cv2.waitKey(0) # Show Cropped Image
Mask = Image_Crop > 10 # Thershold Image to Value of X
Mask = np.array(Mask, dtype=np.uint8)
plt.imshow(Mask, alpha=1) # Set Opacity (Max 1)
ret,Binary = cv2.threshold(Mask,0,255,cv2.THRESH_BINARY)
#plt.imshow(Image_Crop, cmap="gray") # Transform Image to Gray
#plt.show()
plt.imshow(Binary,'gray',vmin=0,vmax=255)
plt.show()
## Number Recognition
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' # Call Location of Tesseract-OCR
data = pytesseract.image_to_string(Binary, lang='eng',config='--psm 6')
print(data)
Here is the image after processing

Tensorflow's convert_image_dtype breaks image

I'm converting a .png image to float32 the following way and I'm obtaining a broken image as shown below. If I remove the tf.image.convert_image_dtype call, everything goes well.
image = tf.io.read_file(filename)
image = tf.image.decode_png(image, channels=3)
image = tf.image.convert_image_dtype(image, tf.float32)
I've also tried different images with different formats like .bmp and .jpg but same thing happens. The code I use to visualize the image generated the above way is just:
a = a.numpy()
a = Image.fromarray(a, 'RGB')
As I've said, if I just remove the tf.image.convert_image_dtype call everything goes well.
Here are the download links of both images (I have less than 10 reputation here so I can't upload photos yet).
original_image
obtained_image
You can convert it back to integer like this
import tensorflow as tf
import numpy as np
from PIL import Image
image = tf.io.read_file("C:\\<your file>.png")
image = tf.image.decode_png(image, channels=3)
image = tf.image.convert_image_dtype(image, tf.float32)
a = image.numpy()
a = (a * 255 / np.max(a)).astype('uint8')
a = Image.fromarray(a, 'RGB')
a.show()

im7 image files to openCV

Able to show the image through matplotlib, however unable to do it through cv2.imshow. The shape of the image is not consistent with opencv required formats. Require help on changing on changing it so it can be shown by the command cv2.imshow
test.jpg is a random jpg file from web
import numpy as np
import cv2
import matplotlib.pyplot as plt
import ReadIM
img = cv2.imread('test.jpg')
vbuff, vatts = ReadIM.extra.get_Buffer_andAttributeList('test.im7')
v_array, vbuff = ReadIM.extra.buffer_as_array(vbuff)
print (np.shape(v_array))
print (v_array[0])
print (np.shape(img))
# Showing image through matplotlib
plt.imshow(v_array[0])
plt.show()
#Showing image through cv2
cv2.imshow('image',v_array[0])
cv2.waitKey(0)
cv2.destroyAllWindows()
# Remove memory
#del(vbuff)
ReadIM.DestroyBuffer(vbuff)
ReadIM.DestroyAttributeListSafe(vatts)
test.im7
Normalizing the image to (0,255) will do the trick
img = cv2.normalize(img, None, 255,0,cv2.NORM_MINMAX,dtype = cv2.CV_8UC1)
cv2.imshow('image',img)

Why matplotlib.pyplot.imsave() and matplotlib.pyplot.imshow() image qualities are different? How to ensure the same quality?

It seems matplotlib.imsave() lightens the image when compared to that of matplotlib.imshow(). For example, look at the code below.
import imageio
import matplotlib.pyplot as plt
image = imageio.imread('image.jpg')
plt.imshow(image)
plt.imsave('image_new.jpg', image)
image_new = imageio.imread('image_new.jpg')
plt.imshow(image_new)
Saved image image_new.jpg (right) is slightly lighter than image.jpg (left).
image_source: https://c1.staticflickr.com/9/8191/8424182610_e23dcc6b4d_b.jpg
I am really ok with your result. so I try it with CV2 and matplotlib:
import imageio
import matplotlib.pyplot as plt
import numpy as np
import cv2; import os
p0 = os.getcwd()
image1 = plt.imread(p0+'\\2.jpg')
image = plt.imread(p0+'\\2.jpg')[:,:,0]
plt.subplot(141);plt.imshow(image1 );plt.title('Original image')
plt.imsave('image_plt.jpg',image )
imageio.imsave('image_imageio.jpg', image)
imagecv2 = image
cv2.imwrite('image_cv2.jpg',imagecv2 )
image_new = plt.imread('image_plt.jpg')[:,:,0]
plt.subplot(2,4,2);plt.title('read after save plt')
plt.imshow(image_new,cmap ='gray')
plt.subplot(2,4,6);plt.title('Diff original image with saved plt')
x=np.abs ( image - image_new)
plt.imshow(x,cmap ='gray')
image_cv2 = plt.imread('image_cv2.jpg')[:,: ]
plt.subplot(2,4,3);plt.title('read after save plt')
plt.imshow(image_new,cmap ='gray')
plt.subplot(2,4,7);plt.title('Diff original image with saved CV2')
x=np.abs ( image - image_cv2)
plt.imshow(x,cmap ='gray')
image_imageio = plt.imread('image_imageio.jpg')
plt.subplot(2,4,4);plt.title('read after save imageio')
plt.imshow(image_new,cmap ='gray')
plt.subplot(2,4,8);plt.title('Diff original image with saved imageio')
x=np.abs ( image - image_imageio)
plt.imshow(x,cmap ='gray')
figManager = plt.get_current_fig_manager()
figManager.window.showMaximized()
plt.savefig('diff.jpg')
Results:

Python: How to resize an image using PIL module

I'm trying to resize an image to 500x500px but got this error:
File "C:\Python27\lib\site-packages\PIL\Image.py", line 1681, in save
save_handler = SAVE[format.upper()] KeyError: 'JPG'
This is the code:
from PIL import Image
img = Image.open('car.jpg')
new_img = img.resize((500,500))
new_img.save('car_resized','jpg')
You need to set the format parameter in your call to the save function to 'JPEG':
from PIL import Image
img = Image.open('car.jpg')
new_img = img.resize((500,500))
new_img.save("car_resized.jpg", "JPEG", optimize=True)
Here is the solution:
from PIL import Image
img = Image.open('car.jpg')
new_img = img.resize((500,500), Image.ANTIALIAS)
quality_val = 90 ##you can vary it considering the tradeoff for quality vs performance
new_img.save("car_resized.jpg", "JPEG", quality=quality_val)
There are list of resampling techniques in PIL like ANTIALIAS, BICUBIC, BILINEAR and CUBIC.
ANTIALIAS is considered best for scaling down.

Categories