I'm trying to download an svg image and open it in opencv for further processing. What I am doing is to convert from svg to png format with cairosvg, open it using Pillow and finally convert to opencv. The problem here is that the image converted in opencv does not look exactly the same as the one in PIL format.
from io import BytesIO
import numpy as np
import requests
from PIL import Image
from cairosvg import svg2png
import cv2
svg_url = 'https://logincdn.msauth.net/16.000.28611.4/content/images/microsoft_logo_ee5c8d9fb6248c938fd0dc19370e90bd.svg'
# Get svg data
svg_data = requests.get(svg_url).content
# Convert from svg to png
png = svg2png(bytestring=svg_data)
# Open png in PIL
pil_img = Image.open(BytesIO(png))
pil_img.show() # This looks good
# Convert to opencv
cv_img = np.array(pil_img.convert('RGB'))[:, :, ::-1].copy() # Taken from https://stackoverflow.com/questions/14134892/convert-image-from-pil-to-opencv-format
cv2.imshow('cv_img', cv_img) # This does not look right
cv2.waitKey(0)
These are the resulting images from PIL and opencv format respectively:
The opencv image does not look right, e.g. the text does not have space between characters.
Why is that and how can I fix it?
As suggested, you have to preserve alpha channel.
import numpy as np
import requests
from io import BytesIO
from PIL import Image
from cairosvg import svg2png
import cv2
svg_url = 'https://logincdn.msauth.net/16.000.28611.4/content/images/microsoft_logo_ee5c8d9fb6248c938fd0dc19370e90bd.svg'
svg_data = requests.get(svg_url).content
png = svg2png(bytestring=svg_data)
pil_img = Image.open(BytesIO(png)).convert('RGBA')
pil_img.save('output/pil.png')
cv_img = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGBA2BGRA)
cv2.imwrite('cv.png', cv_img)
Related
I have performed a shear and horizona flip transformations on an float array saved in a PFM file, then I have saved them as tif files through this code:
import os
from scipy import ndarray
# image processing library
import skimage as sk
from skimage.transform import warp
from skimage import util
from skimage import io
import numpy as np
def shear(image_array: ndarray, shear=10):
tf_augment = sk.transform.AffineTransform(shear=np.deg2rad(shear))
return warp(image_array, tf_augment, order=1, preserve_range=True,
mode='edge')
def horizontal_flip(image_array: ndarray):
return image_array[:, ::-1]
image_path='./train/0006.pfm'
image_to_transform, scale=readPFM(image_path)
flipped_image1=horizontal_flip(image_to_transform)
io.imsave("flipped_image1.tif", flipped_image1)
sheared_image1 =shear(image_to_transform,5)
io.imsave("sheared_image1.tif", sheared_image1)
However, when I try to open these images with PIL framework, it works with the flipped image but not with sheared one:
from PIL import Image
Image.open("sheared_image1.tif")
I got the error
OSError: cannot identify image file 'sheared_image1.tif'
Could anyone explain to me the reason, or how to save my transformed images through skimage framework to be able to read them with PIL (I have to read them with PIL for latter purposes)
I want to convert image (.jpg) to binary array. Because I have to use this array to my scrambler operating on it saved in file. Which library and and functions should I use?
You should take a look at the openCV library.
import cv2
img = cv2.imread('image.jpg', flags=cv2.IMREAD_COLOR)
You can use the python library: PIL & numpy. Click here to learn more about image handling in python.
import numpy
import PIL
img = PIL.Image.open("foo.jpg").convert("L")
imgarr = numpy.array(img)
You can use this code to convert your image to array
# Import the necessary libraries
from PIL import Image
from numpy import asarray
# load the image and convert into
# numpy array
img = Image.open('test.jpg')
arraydata = asarray(img)
# data
print(arraydata)
I want to convert an image loaded
TestPicture = cv2.imread("flowers.jpg")
I would like to run a PIL filter like on the example with the variable
TestPicture
but I'm unable to convert it back and forth between these types.
Is there a way to do these conversions?
Can OpenCV do all of the image filters that are in the PIL package?
Example:
Result:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
threshold_img = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
im_pil = cv2_to_pil(threshold_img)
pytesseract.image_to_string(im_pil)
Out[5]: 'TUM'
Yes OpenCV is more robust and flexible and can perform most of the image processing routines which are available out there, So probably this filter can be done with OpenCV> However, there may not be a straightforward API for that.
Anyways, as far as the conversion of image format from OpenCV to PIL is concerned you may use Image.fromarray as:
import cv2
import numpy as np
from PIL import Image
img = cv2.imread("path/to/img.png")
# You may need to convert the color.
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
im_pil = Image.fromarray(img)
# For reversing the operation:
im_np = np.asarray(im_pil)
But you must keep in mind that, OpenCV follows BGR convention and PIL follows RGB color convention, so to keep the things consistent you may need to do use cv2.cvtColor() before conversion.
Pillow and OpenCV use different formats of images. So you can't just read an image in Pillow and manipulate it into an OpenCV image.
Pillow uses the RGB format as #ZdaR highlighted, and OpenCV uses the BGR format. So, you need a converter to convert from one format to another.
To convert from PIL image to OpenCV use:
import cv2
import numpy as np
from PIL import Image
pil_image=Image.open("demo2.jpg") # open image using PIL
# use numpy to convert the pil_image into a numpy array
numpy_image=numpy.array(pil_img)
# convert to a openCV2 image, notice the COLOR_RGB2BGR which means that
# the color is converted from RGB to BGR format
opencv_image=cv2.cvtColor(numpy_image, cv2.COLOR_RGB2BGR)
To convert from OpenCV image to PIL image use:
import cv2
import numpy as np
from PIL import Image
opencv_image=cv2.imread("demo2.jpg") # open image using openCV2
# convert from openCV2 to PIL. Notice the COLOR_BGR2RGB which means that
# the color is converted from BGR to RGB
color_converted = cv2.cvtColor(opencv_image, cv2.COLOR_BGR2RGB)
pil_image=Image.fromarray(color_converted)
Here are two functions to convert image between PIL and OpenCV:
def toImgOpenCV(imgPIL): # Conver imgPIL to imgOpenCV
i = np.array(imgPIL) # After mapping from PIL to numpy : [R,G,B,A]
# numpy Image Channel system: [B,G,R,A]
red = i[:,:,0].copy(); i[:,:,0] = i[:,:,2].copy(); i[:,:,2] = red;
return i;
def toImgPIL(imgOpenCV): return Image.fromarray(cv2.cvtColor(imgOpenCV, cv2.COLOR_BGR2RGB));
Convert from OpenCV img to PIL img will lost transparent channel. While convert PIL img to OpenCV img will able to keep transparent channel, although cv2.imshow not display it but save as png will gave result normally.
This is my code in python to read TIF and save it as png file.
import numpy as np
from PIL import Image
import matplotlib.image as mpimg
#im.show()
from skimage import io
import matplotlib.pyplot as plt
import matplotlib
import imageio
I = plt.imread('Shoes.TIF')
im= Image.fromarray(I)
print im.size
imageio.imsave('ShoesTest.png', I)
input_filename = "Shoes.TIF"
img =mpimg.imread(input_filename)
imgg= Image.fromarray(img)
print img
imgg.show()
However, when the new image is saved. I get an issue. When I try to check the resolution of the image in photoshop, I get this result.
Original : 240 pixels / inch
Saved Image : 96 pixels / inch
How do I save image in python that retains the resolution of the image? That is why I noticed visual changes in the images. Please help.
i want to convert a Pyglet.AbstractImage object to an PIL image for further manipulation
here are my codes
from pyglet import image
from PIL import Image
pic = image.load('pic.jpg')
data = pic.get_data('RGB', pic.pitch)
im = Image.fromstring('RGB', (pic.width, pic.height), data)
im.show()
but the image shown went wrong.
so how to convert an image from pyglet to PIL properly?
I think I find the solution
the pitch in Pyglet.AbstractImage instance is not compatible with PIL
I found in pyglet 1.1 there is a codec function to encode the Pyglet image to PIL
here is the link to the source
so the code above should be modified to this
from pyglet import image
from PIL import Image
pic = image.load('pic.jpg')
pitch = -(pic.width * len('RGB'))
data = pic.get_data('RGB', pitch) # using the new pitch
im = Image.fromstring('RGB', (pic.width, pic.height), data)
im.show()
I'm using a 461x288 image in this case and find that pic.pitch is -1384
but the new pitch is -1383
This is an open wishlist item:
AbstractImage to/from PIL image.