image file is truncated (bytes not processed) - python

I was trying to read a batch of images in Python and resize them. It gives error as in the title, which I think is because the images are in different sizes. How do I solve this? The code is as following:
from PIL import Image
import numpy as np
for x in range(1,10):
fin = 'path/image%03d.jpg'%(x,)
im = Image.open(fin)
im1 = im.resize((400,400),Image.ANTIALIAS)
fout = 'path/resize/image%03d.jpg'%(x,)
im1.save(fout)

Related

How to shuffle pixels in an image using Python Pillow?

My goal is to shuffle all pixels in a 512x512 Python Pillow image. Also, I need the time performance to be relatively good. What I've tried:
from PIL import Image
import numpy as np
orig = Image.open('img/input2.jpg')
orig_px = orig.getdata()
np_px = np.asarray(orig_px)
np.random.shuffle(np_px)
res = Image.fromarray(np_px.astype('uint8')).convert('RGB')
res.show()
The Preview app gives me the following error:
The file “tmp11g28d6z.PNG” could not be opened.
It may be damaged or use a file format that Preview doesn’t recognise.
I cannot figure out, what went wrong. I would be grateful for any suggestions about fixing this code or trying a different approach to solving this problem.
Main problem that getdata provide you 1d array, and fromarray requires 2d or 3d array. see corrected code. You maybe notice two reshapes. So first reshape make array of pixels. Each pixel has 3 values. Than shuffle them, than reshape in image. If you comment np.random.shuffle(orig_px) you will get original image as is.
from PIL import Image
import numpy as np
orig = Image.open('test.jpg')
orig_px = orig.getdata()
orig_px = np.reshape(orig_px, (orig.height * orig.width, 3))
np.random.shuffle(orig_px)
orig_px = np.reshape(orig_px, (orig.height, orig.width, 3))
res = Image.fromarray(orig_px.astype('uint8'))
res.save('out.jpg')

Opencv Python open dng format

I can't figure out how to open a dng file in opencv.
The file was created when using the pro options of the Samsung Galaxy S7.
The images that are created when using those options are a dng file as well as a jpg of size 3024 x 4032 (I believe that is the dimensions of the dng file as well).
I tried using the answer from here (except with 3 colors instead of grayscale) like so:
import numpy as np
fd = open("image.dng", 'rb')
rows = 4032
cols = 3024
colors = 3
f = np.fromfile(fd, dtype=np.uint8,count=rows*cols*colors)
im = f.reshape((rows, cols,colors)) #notice row, column format
fd.close()
However, i got the following error:
cannot reshape array of size 24411648 into shape (4032,3024,3)
Any help would be appreciated
As far as i know it is possible that DNG files can be compressed (even though it is lossless format), so you will need to decode your dng image first. https://www.libraw.org/ is capable of doing that.
There is python wrapper for that library (https://pypi.python.org/pypi/rawpy)
import rawpy
import imageio
path = 'image.dng'
with rawpy.imread(path) as raw:
rgb = raw.postprocess()
process_raw supports both read and write .dng format raw image. Here is a python example:
import cv2
from process_raw import DngFile
# Download raw.dng for test:
# wget https://github.com/yl-data/yl-data.github.io/raw/master/2201.process_raw/raw-12bit-GBRG.dng
dng_path = "./raw-12bit-GBRG.dng"
dng = DngFile.read(dng_path)
rgb1 = dng.postprocess() # demosaicing by rawpy
cv2.imwrite("rgb1.jpg", rgb1[:, :, ::-1])
rgb2 = dng.demosaicing(poww=0.3) # demosaicing with gamma correction 0.3
cv2.imwrite("rgb2.jpg", rgb2[:, :, ::-1])
DngFile.save(dng_path + "-save.dng", dng.raw, bit=dng.bit, pattern=dng.pattern)

Python creating video from images using opencv

I was trying to create a video to show the dynamic variation of the data, like just continuously showing the images one by one quickly, so I used images (the images just called 1,2,3,4,.....) and wrote the following code:
import cv2
import numpy as np
img=[]
for i in range(0,5):
img.append(cv2.imread(str(i)+'.png'))
height,width,layers=img[1].shape
video=cv2.VideoWriter('video.avi',-1,1,(width,height))
for j in range(0,5):
video.write(img)
cv2.destroyAllWindows()
video.release()
and a error was raised:
TypeError: image is not a numpy array, neither a scalar
I think I used the list in a wrong way but I'm not sure. So where did I do wrong?
You are writing the whole array of frames. Try to save frame by frame instead:
...
for j in range(0,5):
video.write(img[j])
...
reference
You can read the frames and write them to video in a loop. Following is your code with a small modification to remove one for loop.
import cv2
import numpy as np
# choose codec according to format needed
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
video = cv2.VideoWriter('video.avi', fourcc, 1, (width, height))
for j in range(0,5):
img = cv2.imread(str(i) + '.png')
video.write(img)
cv2.destroyAllWindows()
video.release()
Alternatively, you can use skvideo library to create video form sequence of images.
import numpy as np
import skvideo.io
out_video = np.empty([5, height, width, 3], dtype = np.uint8)
out_video = out_video.astype(np.uint8)
for i in range(5):
img = cv2.imread(str(i) + '.png')
out_video[i] = img
# Writes the the output image sequences in a video file
skvideo.io.vwrite("video.mp4", out_video)
You can use this pip package. It provides CLI commands to make video from images.
img_to_vid.py -f images_directory

To get image from cifat10-dataset

I am trying to get images from cifar10-dataset. When i rebuild image from array,
i see 9 same images in one picture, i don't know what is the problem.
When i load image from data, single_img shape (3072,). After that, i reshape
my single_img varible (32, 32, 3). I don't know where is the problem.
Here my code;
import cPickle
from PIL import Image
import numpy as np
f = open("/home/leo/Downloads/cifar-10-batches-py/data_batch_1", "rb")
tupled_data= cPickle.load(f)
f.close()
img = tupled_data['data']
single_img = np.array(img[0])
single_img_reshaped = single_img.reshape(32, 32 ,3)
j = Image.fromarray(single_img_reshaped)
j.save("/home/leo/Desktop/blabla.bmp")
Example image;
Be sure to be careful about the format of the pixel array of the image..
[R....G....B]
So you just change its format to
[[[R,G,B],....,[R,G,B]]
[[R,G,B],....,[R,G,B]]
[[R,G,B],....,[R,G,B]]]
But
single_img_reshaped = single_img.reshape(32, 32 ,3)
don't do it like before.

Imsave changes the color of an image if converted using numpy and scipy.misc.pilutil

So I have some problems with a simple image processing task. The code looks like this:
from scipy.misc.pilutil import imread, imsave
import numpy as np
infile = imread('in.png')
outfile = np.multiply(infile, 1.0).astype(int) # Just an example of array manipulation
print type(infile) == type(outfile) # True
# Exactly the same
print infile
print outfile
imsave('out.png', outfile)
This produces an array with different grayscale colors than the input image. It magically works if I change the manipulation to be outfile = np.multiply(infile, 1) (with an int instead of a float).
Can someone explain to me what I don't understand? The input image is a greyscale image.

Categories