I have an OpenCV image I'm trying to save as a .tiff file:
img_to_save = Image.fromarray(array.astype("uint8"))
img_to_save.save(os.path.join(args[2], "1.tif"))
The file is saved but the resolution metadata is missing
Warning: Invalid resolution 0 dpi. Using 70 instead. when I run tesseract on it.
I tried the following but I'm not sure how to convert resolution to dpi correctly or if it adds the metadata to the file:
img_to_save.save(os.path.join(args[2], "1.tif"), dpi=(array.shape[0], array.shape[1]))
How can I include the correct image resolution in the tiff?
Try using dpi=(72,72).
Check in Terminal with:
exiftool YourFile.tif
or with ImageMagick:
magick identify -verbose YourFile.tif
or with:
tiffinfo YourFile.tif
Related
I've been trying to find the best way to convert a given GIF image to a sequence of BMP files using python.
I've found some libraries like Wand and ImageMagic but still haven't found a good example to accomplish this.
Reading an animated GIF file using Python Image Processing Library - Pillow
from PIL import Image
from PIL import GifImagePlugin
imageObject = Image.open("./xmas.gif")
print(imageObject.is_animated)
print(imageObject.n_frames)
Display individual frames from the loaded animated GIF file
for frame in range(0,imageObject.n_frames):
imageObject.seek(frame)
imageObject.show()
from wand.image import Image
with Image(filename="animation.gif") as img:
img.coalesce()
img.save(filename="frame%02d.bmp)
Use Image.coalesce() to rebuild optimized frames, and ImageMagick's "Percent Escapes" format (%02d) to write image frame as a separate BMP file.
In Imagemagick, which comes with Linux and can be installed for Windows or Mac OSX,
convert image.gif -coalesce image.bmp
the results will be image-0.bmp, image-1.bmp ...
Use convert for Imagemagick 6 or replace convert with magick for Imagemagick 7.
Given the short, 5 page PDF file (attached at the bottom), and the following python code to convert to a multi-page TIFF:
from wand.image import Image
with Image(filename='5-page-pdf.pdf', resolution=200) as img:
img.type = "grayscale"
img.format = "tiff"
img.compression = "lzw"
img.save(filename="test.tiff")
results in a TIFF file that has pages 2-4 as what appears to be black text on a dark-grey (or maybe transparent) background. Other image processing libraries cannot open the file or render it.
Converting the same PDF with ImageMagick, which Wand uses, works just fine
convert -density 200 5-page-pdf.pdf -type grayscale -compress lzw 5-page-pdf.tiff
this produces a file that does work with other imaging libraries and looks correct in a TIFF viewer.
I've tried removing the alpha channel, I've tried setting the background color to 'White', and a few other things, to no avail. The TIFF that comes out of Wand is always garbled. If it's doable in ImageMagick it should be doable in Wand, right? What parameter or setting am I missing?
Original PDF
Wand Produced TIFF
Looks like setting the img.alpha_channel property is not propagating across the pages.
Try this workaround
from wand.api import library
from wand.image import Image
with Image(filename="5-page-pdf.pdf", resolution=200) as img:
img.type = 'grayscale'
img.compression = "lzw"
# Manually iterate over all page, and turn off alpha channel.
library.MagickResetIterator(img.wand)
for idx in range(library.MagickGetNumberImages(img.wand)):
library.MagickSetIteratorIndex(img.wand, idx)
img.alpha_channel = 'off'
img.save(filename="test.tiff")
I'm trying to convert a .tif image in python using the module skimage.
It's not working properly.
from skimage import io
img = io.imread('/content/IMG_0007_4.tif')
io.imsave('/content/img.jpg', img)
Here is the error:
/usr/local/lib/python3.6/dist-packages/imageio/core/functions.py in get_writer(uri, format, mode, **kwargs)
if format is None:
raise ValueError(
"Could not find a format to write the specified file " "in mode %r" % mode)
ValueError: Could not find a format to write the specified file in mode 'i'
EDIT 1:
A method I found to do this was to open using skimage, convert it to 8bits and then save it as png.
Anyway I can't save it as .jpg
img = io.imread('/content/IMG_0007_4.tif',as_gray=True)
img8 = (img/256).astype('uint8')
matplotlib.image.imsave('/content/name.png', img8)
You have not provided an image plugin in the save command. See https://scikit-image.org/docs/dev/api/skimage.io.html#skimage.io.imsave where it says:
When saving a JPEG, the compression ratio may be controlled using the
quality keyword argument which is an integer with values in [1, 100]
where 1 is worst quality and smallest file size, and 100 is best
quality and largest file size (default 75). This is only available
when using the PIL and imageio plugins.
I found a good tool called ImageMagick it can be installed in linux.
To call it inside python code i just did this.
os.system("convert image.png -colorspace RGB image.jpg ")
I am taking a screen-shot (PNG format) resizing it, and writing it back out in TIF format, via scipy.misc module (imread, imresize, imsave functions). The TIF format image is to be fed into Tesseract-OCR. However, Tesseract is complaining that the dpi specified in the TIF file's metadata is 0. How can one specify this when saving the image via scipy.misc.imsave or any other method?
Without analyzing where your problems exactly come from, the approach of Mark (maybe that's enough for you; maybe not; i can imagine there is something else in your code which might be the reason) can be emulated by using Pillow (and i don't see an option for this within scipy's wrapper).
Actually, instead of rewriting tags as he does, we care about these while doing our original task. In practice both approaches should be okay.
With a very high probability, scipy is already using Pillow under the hood (Note that Pillow (https://python-pillow.org/) is not a dependency of SciPy, but the image manipulation functions indicated in the list below are not available without it.; this list contains imsave).
from scipy.misc import ascent # test image
import PIL.Image
scipy_img = ascent().astype('uint8')
arr2im = PIL.Image.fromarray(scipy_img)
arr2im.save('test.tif', format='TIFF',
dpi=(100., 100.), # there still seems to be a bug when using int's here
compression='tiff_lzw',)
Checking with exiftool:
ExifTool Version Number : 10.63
File Name : test.tif
...
Image Width : 512
Image Height : 512
Bits Per Sample : 8
Compression : LZW
...
X Resolution : 100
Y Resolution : 100
...
Resolution Unit : inches
Image Size : 512x512
Megapixels : 0.262
Please file this one under "any other method" :-)
You can set the resolution with exiftool like this:
exiftool SomeImage.tif -xresolution=300 -yresolution=300 -resolutionunit=inches
Check it with ImageMagick:
identify -verbose SomeImage.tif
Image: SomeImage.tif
Format: TIFF (Tagged Image File Format)
Mime type: image/tiff
Class: DirectClass
Geometry: 100x100+0+0
Resolution: 300x300
Print size: 0.333333x0.333333
...
...
I am suggesting you shell out to run this command with os.system().
A Python wrapper exists, but I have never used it and cannot vouch for it.
I try to apply image filters using python's PIL. The code is straight forward:
im = Image.open(fnImage)
im = im.filter(ImageFilter.BLUR)
This code works as expected on PNGs, JPGs and on 8-bit TIFs. However, when I try to apply this code on 16-bit TIFs, I get the following error
ValueError: image has wrong mode
Note that PIL was able to load, resize and save 16-bit TIFs without complains, so I assume that this problem is filter-related. However, ImageFilter documentation says nothing about 16-bit support
Is there any way to solve it?
Your TIFF image's mode is most likely a "I;16".
In the current version of ImageFilter, kernels can only be applied to
"L" and "RGB" images (see source of ImageFilter.py)
Try converting first to another mode:
im.convert('L')
If it fails, try:
im.mode = 'I'
im = im.point(lambda i:i*(1./256)).convert('L').filter(ImageFilter.BLUR)
Remark: Possible duplicate from Python and 16 Bit Tiff
To move ahead, try using ImageMagick, look for PythonMagick hooks to the program. On the command prompt, you can use convert.exe image-16.tiff -blur 2x2 output.tiff. Didn't manage to install PythonMagick in my windows OS as the source needs compiling.