Converting PNG file to bitmap array in Python - python

I would like to convert a PNG image to a 2 dimensional array where each array holds a list of the RGB values of that specific pixel. How could one create a program to read-in a *.png file and convert to this type of data structure?

If you have PIL installed then you can create an image with Image.open and get the colors like so:
data = [image.getpixel((x, y)) for x in range(image.width) for y in range(image.height)]

You can use the existing pygame module. Import a file into a Surface using pygame.image.load. You can then access the bit array from this using pygame.surfarray.array2d. Please see the Pygame docs for more information.

You can use wand for such basic tasks. The syntax is very easy to read unlike other ImageMagik libs. Basically you'd do something like:
from wand.image import Image
from wand.display import display
array = []
with Image(filename='yourfile.png') as img:
array.append(img.channel_images) # this is most likely wrong, but it should be something similar
It will be along those lines. Once I leave the office I will try this out.

Related

Reading and saving tif images with python

I am trying to read this tiff image with python. I have tried PIL to and save this image. The process goes smoothly, but the output image seems to be plain dark. Here is the code I used.
from PIL import Image
im = Image.open('file.tif')
imarray = np.array(im)
data = Image.fromarray(imarray)
data.save('x.tif')
Please let me know if I have done anything wrong, or if there is any other working way to read and save tif images. I mainly need it as NumPy array for processing purposes.
The problem is simply that the image is dark. If you open it with PIL, and convert to a Numpy array, you can see the maximum brightness is 2455, which on a 16-bit image with possible range 0..65535, means it is only 2455/65535, or 3.7% bright.
from PIL import Image
# Open image
im = Image.open('5 atm_gain 80_C001H001S0001000025.tif')
# Make into Numpy array
na = np.array(im)
print(na.max()) # prints 2455
So, you need to normalise your image or scale up the brightnesses. A VERY CRUDE method is to multiply by 50, for example:
Image.fromarray(na*50).show()
But really, you should use a proper normalisation, like PIL.ImageOps.autocontrast() or OpenCV normalize().

How to check the channel order of an image?

Question
With an image loaded into Python as shown below, how do I know which order the channels are in? (e.g. BGR or RGB)
Code
from PIL import Image
import numpy as np
image_pil = Image.open("Stonehenge.jpg")
image_np = np.array(image_pil)
image_np[0][0]
Result
array([ 52, 123, 155], dtype=uint8)
Specific question
How do I know whether the 52 corresponds to the red channel, the blue channel, or a different channel? Or does this question not make sense on a conceptual level?
Notes
In a similar question for Java instead of Python, one person claims:
If you are reading in the image file, or you have access to the code
that reads in the file, know it is:
BGR order if you used cv2.imread(),
RGB order if you used mpimg.imread(), (assuming import matplotlib.image as mpimg)
If you don't know how the file was opened, the accepted answer
BufferedImage is great for Java.
Since you use PIL and you don't specify any other mode to load the Image with, you get R G B.
You could verify that by checking the "mode" attribute on the Image instance:
image_pil.mode # should return the string 'RGB'
Pillow supports the array interface, via image_pil.__array_interface__ magic method, so when when you create the ndarray numpy just uses that. i.e., it doesn't know anything about the colour channel order. If you have an image file stored as BGR, and you load it like this, you will get blue data in the red channel and vice-versa, and it would look wrong when you display it.

I have text file with a 2D matrix in it. How do turn this into a grey scale image in python?

I'm fairly new with python so I'm not really sure where to start. All I have done is I imported the text file to python. I was suggested to use matshow.py but I don't know how I would use the text file to create the actual image.
If you can contrive to get your text file into a numpy array then this kind of code will work. Just research, or ask another question, about reading a text file into a numpy array.
>>> from PIL import Image
>>> import numpy as np
>>> pic = np.zeros((100,100), dtype=np.int8)
>>> image = Image.fromarray(pic)
>>> image.show()
Here I import the Image class from the PIL library. Then I create a 100x100 array of zeroes in pic using numpy. I use a method from Image to make this into an Image object and then display the (utterly uninteresting, completely black) result.
What exactly are you trying to achieve, your point isn't clear.
if you are trying to draw an image using a matrix.
you will need to look into PIL.
Here is the link to download the library and here is the link for the documentations.
Try
Matrix = loadtxt(filename)
imshow(Matrix)
These functions come from the numpy and matplotlib libraries, respectivelly.

RGB Values Being Returned by PIL don't match RGB color

I'm attempting to make a reasonably simple code that will be able to read the size of an image and return all the RGB values. I'm using PIL on Python 2.7, and my code goes like this:
import os, sys
from PIL import Image
img = Image.open('C:/image.png')
pixels = img.load()
print(pixels[0, 1])
now this code was actually gotten off of this site as a way to read a gif file. I'm trying to get the code to print out an RGB tuple (in this case (55, 55, 55)) but all it gives me is a small sequence of unrelated numbers, usually containing 34.
I have tried many other examples of code, whether from here or not, but it doesn't seem to work. Is it something wrong with the .png format? Do I need to further code in the rgb part? I'm happy for any help.
My guess is that your image file is using pre-multiplied alpha values. The 8 values you see are pretty close to 55*34/255 (where 34 is the alpha channel value).
PIL uses the mode "RGBa" (with a little a) to indicate when it's using premultiplied alpha. You may be able to tell PIL to covert the to normal "RGBA", where the pixels will have roughly the values you expect:
img = Image.open('C:/image.png').convert("RGBA")
Note that if your image isn't supposed to be partly transparent at all, you may have larger issues going on. We can't help you with that without knowing more about your image.

PyQt/PySide: How do I convert QImage into OpenCV's MAT format

I'm looking to create a function for converting a QImage into OpenCV's (CV2) Mat format from within the PyQt.
How do I do this? My input images I've been working with so far are PNGs (either RGB or RGBA) that were loaded in as a QImage.
Ultimately, I want to take two QImages and use the matchTemplate function to find one image in the other, so if there is a better way to do that than I'm finding now, I'm open to that as well. But being able to convert back and forth between the two easily would be ideal.
Thanks for your help,
After much searching on here, I found a gem that got me a working solution. I derived much of my code from this answer to another question: https://stackoverflow.com/a/11399959/1988561
The key challenge I had was in how to correctly use the pointer. The big thing I think I was missing was the setsize function.
Here's my imports:
import cv2
import numpy as np
Here's my function:
def convertQImageToMat(incomingImage):
''' Converts a QImage into an opencv MAT format '''
incomingImage = incomingImage.convertToFormat(4)
width = incomingImage.width()
height = incomingImage.height()
ptr = incomingImage.bits()
ptr.setsize(incomingImage.byteCount())
arr = np.array(ptr).reshape(height, width, 4) # Copies the data
return arr
I tried the answer given above, but couldn't get the expected thing. I tried this crude method where i saved the image using the save() method of the QImage class and then used the image file to read it in cv2
Here is a sample code
def qimg2cv(q_img):
q_img.save('temp.png', 'png')
mat = cv2.imread('temp.png')
return mat
You could delete the temporary image file generated once you are done with the file.
This may not be the right method to do the work, but still does the required job.

Categories

Resources