I'm trying to open a tiff stack using gdal in python. It is a single file, within which are mutliple tiff files. When I open it in ImageJ, I can scroll through the stack. But doing "gdal.Open(file).ReadAsArray() only loads the first tiff file. Is there a way I can load the whole stack?
Iterate over GetSubDatasets and (in case all TIFF pages have the same dimensions) create a single numpy array:
import numpy, gdal, gdalconst
dataset = gdal.Open("multipage.tiff", gdalconst.GA_ReadOnly)
data = numpy.array([gdal.Open(name, gdalconst.GA_ReadOnly).ReadAsArray()
for name, descr in dataset.GetSubDatasets()])
Related
I have a dataset containing 3000 images in train and 6000 images in test. It's 320x320 rgb png files. I thought that I can load this entire dataset into memory (since it's just 100mb), but then I try to do that I'm getting "[Errno 24] Too many open files: ..." error. Code of loading looks like that:
train_images = []
for index, row in dataset_p_train.iterrows():
path = data_path / row.img_path
train_images.append(Image.open(path))
I know that I'm opening 9000 files and not closing them which isn't a good practice, but unfortunately for my classificator I heavily rely on PIL img.getcolors() method, so I really want to store that dataset in memory as list of PIL images and not as a numpy array of 3000x320x320x3 uint8 to avoid casting them into PIL image each time I need colors of image.
So, what should I do? Somehow increase limit of opened files? Or there is a way to make PIL images reside entirely in memory without being "opened" from disk?
Image.open is lazy. It will not load the data until you try to do something with it.
You can call the image's load method to explicitly load the file contents. This will also close the file, unless the image has multiple frames (for example, an animated GIF).
See File Handling in Pillow for more details.
I have a multi-page tiff file (merged.tiff) out of which I need to extract individual images in their original format. PIL allows you to iterate through pages and writing them to disk in a format I need (png/jpg).
Ex:
from PIL import Image
img = Image.open('merged.tiff')
for i in range(img.n_frames):
try:
img.seek(i)
img.save(f'individual_{i}.jpg')
img.save(f'individual_{i}.png')
except EOFError:
break
But is there a way to know the original format of those images?
I have tried with tifffile and tiffany which allow me to convert the pages to a numpy array and then write to disk as an image, but they don't allow me to know the source format of the images contained in the TIFF file.
In the most general case, I believe this is impossible, because it is perfectly feasible to take, say, a JPEG image and include it in the TIFF file as an uncompressed RGB array.
Realistically, though, you should be able to look at some of the tags of the TIFF file, e.g. Compression, to make an educated guess about what the image used to be. Tools like tiffinfo and tiffdump (from the libtiff package) can be used to examine the TIFF file.
I want to save an image/an array as an OIB File.
I have tried using the oiffile library. I am able to open and read OIB files, but I want to save an image as an OIB File.
Since oiffile uses cv2 structure for opening/closing images (via numpy arrays), so you might be opening the image using imread(). Then you can use imwrite() for saving/writing the image file to a destination path.
I'm using Pillow (version 5.2.0) on Python3 to open both PNG and BMP images, and display them with a Tkinter GUI. The PNG images display correctly with no issues, however, I'm encountering an IOError ("Unsupported BMP compression") with some of the BMP images, when Pillow's BmpImagePlugin.py is used.
Using the bitmap plugin's source and some print statements, I found that the exception is thrown at line 193, and that the images causing the exception are compressed using RLE8 (denoted by the dictionary on line 63); all others work because they're a RAW format.
It would seem to me that if a compression type is listed in that dictionary it should be supported, but apparently that isn't the case.
My question: is anyone aware of a workaround in Pillow or of any other python library that can open RLE8 bitmap images?
Here's an image displaying my PATH environment, as well as the command-line error described in a comment below.
Path issues
I note that your first image (test1.bmp) appears to be corrupt and ImageMagick reports it has incorrect length.
Your second image does not appear to be compressed with RLE8 compression and also is a palettised image, but with alpha/transparency.
Your third image is palletised, non-alpha with RLE8 compression.
My version of PIL can read only the second file - the first and third, which are RLE encoded cannot be read.
You asked for a workaround - may I suggest pyvips which can read the files without issues:
import pyvips
from PIL import Image
# Load troublesome file using vips, and write to a memory buffer
image = pyvips.Image.new_from_file('test1.bmp')
mem_img = image.write_to_memory()
# Read from memory buffer into Numpy array
imgnp=np.frombuffer(mem_img, dtype=np.uint8).reshape(image.height, image.width, 3)
# Convert Numpy array to PIL Image and write to disk
Image.fromarray(imgnp).save('result.png')
A multipage tiff can be saved to a file using PIL: im.save(filepath, save_all=True). My question is how to convert a list of numpy arrays to the im object recognised by PIL. im = PIL.Image.fromarray() doesn't accept a list.
This functionality was just added to Pillow v.4.1.0.dev0
https://github.com/python-pillow/Pillow/pull/2406
There are also some other solutions with other libs. E.g. with tifffile How to create a multiple frame image using Python PIL