Can I get CMY and K from Python Pillow? - python-imaging-library

I am using pillow to modify images. I need to convert RGB to CMYK. Pillow does the subtraction from 255 method and ignores black. I am currently using a floyd_steinberg method that plows through each pixel and gets an average from neighbors. It works but is very slow. Is there a way to get Pillow to include black in the CMYK conversion? Is there possibly another python library that can do the job if Pillow will not perform the task?

Related

tesseract cannot read clear single line

So I have this png image here
and when I try to read it with tesseract on the command line, I get some random character
❯ tesseract Selection_002.png stdout --psm 7
Warning. Invalid resolution 0 dpi. Using 70 instead.
ale PR Me)
I'm running tesseract version 4.0.0-beta.1-370-g8b64 on ubuntu.
I would have guessed that this image would be easy to read for tesseract?
I've gone through trying to resize the image and "cleaning" it up but there's no much noise to clean on that. What Am I doing wrong?
Please try inverting the image color. (Black text on white).
I tried with your image as well as inverting the color. Both gave successful results.

Converting PIL image to VIPS image

I'm working on some large histological images using Vips image library. Together with the image I have an array with coordinates. I want to make a binary mask which masks out the part of the image within the polygon created by the coordinates. I first tried to do this using vips draw function, but this is very inefficiently and takes forever (in my real code the images are about 100000 x 100000px and the array of polygons are very large).
I then tried creating the binary mask using PIL, and this works great. My problem is to convert the PIL image into an vips image. They both have to be vips images to be able to use the multiply-command. I also want to write and read from memory, as I believe this is faster than writing to disk.
In the im_PIL.save(memory_area,'TIFF') command I have to specify and image format, but since I'm creating a new image, I'm not sure what to put here.
The Vips.Image.new_from_memory(..) command returns: TypeError: constructor returned NULL
from gi.overrides import Vips
from PIL import Image, ImageDraw
import io
# Load the image into a Vips-image
im_vips = Vips.Image.new_from_file('images/image.tif')
# Coordinates for my mask
polygon_array = [(368, 116), (247, 174), (329, 222), (475, 129), (368, 116)]
# Making a new PIL image of only 1's
im_PIL = Image.new('L', (im_vips.width, im_vips.height), 1)
# Draw polygon to the PIL image filling the polygon area with 0's
ImageDraw.Draw(im_PIL).polygon(polygon_array, outline=1, fill=0)
# Write the PIL image to memory ??
memory_area = io.BytesIO()
im_PIL.save(memory_area,'TIFF')
memory_area.seek(0)
# Read the PIL image from memory into a Vips-image
im_mask_from_memory = Vips.Image.new_from_memory(memory_area.getvalue(), im_vips.width, im_vips.height, im_vips.bands, im_vips.format)
# Close the memory buffer ?
memory_area.close()
# Apply the mask with the image
im_finished = im_vips.multiply(im_mask_from_memory)
# Save image
im_finished.tiffsave('mask.tif')
You are saving from PIL in TIFF format, but then using the vips new_from_memory constructor, which is expecting a simple C array of pixel values.
The easiest fix is to use new_from_buffer instead, which will load an image in some format, sniffing the format from the string. Change the middle part of your program like this:
# Write the PIL image to memory in TIFF format
memory_area = io.BytesIO()
im_PIL.save(memory_area,'TIFF')
image_str = memory_area.getvalue()
# Read the PIL image from memory into a Vips-image
im_mask_from_memory = Vips.Image.new_from_buffer(image_str, "")
And it should work.
The vips multiply operation on two 8-bit uchar images will make a 16-bit uchar image, which will look very dark, since the numeric range will be 0 - 255. You could either cast it back to uchar again (append .cast("uchar") to the multiply line) before saving, or use 255 instead of 1 for your PIL mask.
You can also move the image from PIL to VIPS as a simple array of bytes. It might be slightly faster.
You're right, the draw operations in vips don't work well with very large images in Python. It's not hard to write a thing in vips to make a mask image of any size from a set of points (just combine lots of && and < with the usual winding rule), but using PIL is certainly simpler.
You could also consider having your poly mask as an SVG image. libvips can load very large SVG images efficiently (it renders sections on demand), so you just magnify it up to whatever size you need for your raster images.

How to detect simple text with Tesseract ORC?

I'm trying to convert simple image with numbers to text using https://github.com/tesseract-ocr/tesseract. I compiled latest version from github with Leptonica and other libs required for image process.
My image looks like this:
I'm trying to convert it like this: /usr/local/bin/tesseract '/home/var/img2text/phone.png' out but instead of numbers something like 3m mam. what could be the problem?
The image is small and the quality of it is a little low, try the following:
1- Change its DPI to 300
2- Resize the image 2x and apply Resample interpolation.
3- Make sure it is a B/W image.
Here are some useful links:
https://code.google.com/p/tesseract-ocr/wiki/ImproveQuality
image processing to improve tesseract OCR accuracy

PIL: converting an image with mode "I" to "RGB" results in a fully white image

The image at the end of this question is a PNG with mode I, which stands for Indexed, as far as I can tell.
I'm trying to create a thumbnail out of it, and save it as JPG with PIL.
However, is I leave the mode alone, PIL won't let me resize it with error unable to generate thumbnail: cannot write mode I as JPEG.
If I convert it to RGB, the result will be a fully white image.
Is there a way to fix this?
https://www.dropbox.com/s/2d1edk2iu4ixk25/NGC281.png
The input image is a 16-bit grayscale PNG, and it appears PIL has a problem with this. Manually converting it to an 8-bit image before further processing makes it work again.
The problem may originate inside PIL itself. The PyPNG homepage asserts
..PIL only has internal representations (PIL mode) for 1-bit and 8-bit channel values. This makes me wonder if PIL can read PNG files with bit depth 2 or 4 (greyscale or palette), and also bit depth 16 (which PNG supports for greyscale and RGB images).
Then again, that page is from 2009. It could be worth tracking down where PIL is maintained from, and report this as a bug (? Or possibly a feature request?).

Tesseract Trained data

Am trying to extract data from reciepts and bills using Tessaract , am using tesseract 3.02 version .
am using only english data , Still the output accuracy is about 60%.
Is there any trained data available which i just replace in tessdata folder
This is the image nicky provided as a "typical example file":
Looking at it I'd clearly say: "Forget it, nicky! You cannot train Tesseract to recognize 100% of text from this type of image!"
However, you could train yourself to make better photos with your iPhone 3GS (that's the device which was used for the example pictures) from such type of receipts. Here are a few tips:
Don't use a dark background. Use white instead.
Don't let the receipt paper crumble. Straighten it out.
Don't place the receipt loosely on an uneven underground. Fix it to a flat surface:
Either place it on a white sheet of paper and put a glas platen over it.
Or use some glue and glue it flat on a white sheet of paper without any bend-up edges or corners.
Don't use a low resolution like just 640x480 pixels (as the example picture has). Use a higher one, such as 1280x960 pixels instead.
Don't use standard exposure. Set the camera to use extremely high contrast. You want the letters to be black and the white background to be really white (you don't need the grays in the picture...)
Try to make it so that any character of a 10-12 pt font uses about 24-30 pixels in height (that is, make the image to be about 300 dpi for 100% zoom).
That said, something like the following ImageMagick command will probably increase Tesseract's recognition rate by some degree:
convert \
http://i.stack.imgur.com/q3Ad4.jpg \
-colorspace gray \
-rotate 90 \
-crop 260x540+110+75 +repage \
-scale 166% \
-normalize \
-colors 32 \
out1.png
It produces the following output:
You could even add something like -threshold 30% as the last commandline option to above command to get this:
(You should play a bit with some variations to the 30% value to tweak the result... I don't have the time for this.)
Taking accurate info from a receipt is not impossible with tesseract. You will need to add image filters and some other tools such as OpenCV, NumPy ImageMagick alongside Tesseract. There was a presentation at PyCon 2013 by Franck Chastagnol where he describes how his company did it.
Here is the link:
http://pyvideo.org/video/1702/building-an-image-processing-pipeline-with-python
You can get a much cleaner post-processed image before using Tesseract to OCR the text. Try using the Background Surface Thresholding (BST) technique rather than other simple thresholding methods. You can find a white paper on the subject here.
There is an implementation of BST for OpenCV that works pretty well https://stackoverflow.com/a/22127181/3475075
i needed exactly the same thing and i tried some image optimisations to improve the output
you can find my experiment with tessaract here
https://github.com/aryansbtloe/ExperimentWithTesseract