How to read the data of a raw image in python - approach - python

I am interested in reading the rgb data of a raw image using python. I would like to analyze the rgb of the RAW image with NO filtering and processing done by the DSLR. How would you recommend proceeding? What library etc.? Storing as a numpy array, if possible would be advantageous, I believe. Using openCV was my initial idea, do you recommend anything else?
Like I said, I want to analyze the image as RAW as possible, hence pre-color filter if possible.
Thank you.

If you have the raw image ("my_picture.raw")? You could totally use OpenCV-Python to look at it.
raw_data = imread('my_picture.raw')
This should give you a numpy array of the pixels that your raw file contains.
Then, you can do some basic operations on the data (accessing pixels, doing object/feature recognition, etc.). There's a ton of detail on their website: https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_core/py_basic_ops/py_basic_ops.html#basic-ops
If you don't have the raw image, then I'm not sure how to "undo" the processing of the DSLR, or if you can!
You don't have to use OpenCV, necessarily. If you have access to a Matlab license, you should check it out (easier to use IMO). Matlab has a very powerful set of image processing tools.

Related

How do I read an arbitrary image file format (PNG, JPEG, TIFF, BMP) in Python using only the standard library?

I'm an experienced Python programmer with plenty of image manipulation and computer vision experience. I'm very familiar with all of the standard tools like PIL, Pillow, opencv, numpy, and scikit-image.
How would I go about reading an image into a Python data format like a nested list, bytearray, or similar, if I only had the standard library to work with?
I realize that different image formats have different specifications. My question is how I would even begin to build a function that reads any given format.
NOTE Python 2.6 had a jpeg module in the standard library that has since been deprecated. Let's not discuss that since it is unsupported.
If you're asking how to implement these formats "from scratch" (since the standard libraries don't do this), then a good starting point would be the format specification.
For PNG, this is https://www.w3.org/TR/2003/REC-PNG-20031110/. It defines the makeup of a PNG stream, consisting of the signature (eight bytes, 8950 4e47 0d0a 1a0a, which identifies the file as a PNG image) and a number of data chunks that contain meta data, palette information and the image itself. (It's certainly a substantial project to take on, if you really don't want to use the existing libraries, but not overly so.)
For BMP, it's a bit easier since the file already contains the uncompressed pixel data and you only need to know how to find the size and offset; some of the format definition is on Wikipedia (https://en.wikipedia.org/wiki/BMP_file_format) and here: http://www.digicamsoft.com/bmp/bmp.html
JPG is much trickier. The file doesn't store pixels, but rather "wavelets" which are transformed into the pixel map you see on the screen. To read this format, you'll need to implement this transformation function.

Making a 3 Colour FITS file using aplpy

I am trying to make a three colour FITS image using the $aplpy.make_rgb_image$ function. I use three separate FITS images in RGB to do so and am able to save a colour image in png, jpeg.... formats, but I would prefer to save its as a FITS file.
When I try that I get the following error.
IOError: FITS save handler not installed
I've tried to find a solution in the web for a few days but was unable to get any good results.
Would anyone know how to get such a handler installed, or perhaps any other approach I could use to get this done?
I don't think there is enough information for me to answer your question completely; for example, I don't know what call you are making to perform the "image" "save", but I can guess:
FITS does not store RGB data like you wish it to. FITS can store multi-band data as individual monochromatic data layers in a multi-extension data "cube". Software, including ds9 and aplpy, can read that FITS data cube and author RGB images in RGB formats (png, jpg...). The error you see comes from PIL, which has no backend to author FITS files (I think, but the validity of that point doesn't matter).
So I think that you should use aplpy.make_rgb_cube to save a 3 HDU FITS cube based your 3 input FITS files, then import that FITS cube back into aplpy and use aplpy.make_rgb_image to output RGB compatible formats. This way you have the saved FITS cube in near native astronomy formats, and a means to create RGB formats from a variety of tools that can import that cube.

Getting pixel data from a PythonMagick image?

Does anyone know a way get the pixel data from a PythonMagick.Image instance without having to write it to disk first?
For instance, I can read in an image using:
import PythonMagick
im = PythonMagick.Image('image.jp2')
I would now like to be able to get the uncompressed image data so that I can use it in something else like NumPy or matplotlib, but I can't seem to find any way to do this. I would just use matplotlib or PIL directly but the image format I'm reading in is JPEG 2000 which is only supported by PythonMagick as far as I know.
Any suggestions?
Disclaimer: I don't have PythonMagick built where I am right now and am no expert, so (1) any or all of the following may be wrong, (2) it will certainly be less specific than you'd like, and (3) if someone else knows better I hope they won't be put off by seeing an answer already here. Anyway:
From a quick look at the code, it looks as if you can read pixel values one by one using the pixelColor method on the Image class. This returns a PythonMagick.Color value, from which you can extract R,G,B components. The underlying C++ library supports reading out lots of pixels at a time using Image::writePixels, which is also present in PythonMagick.Image; but I think the proper use of that method depends on other things that aren't implemented in PythonMagick. That's a pity, because I bet it would have been much much more efficient than reading one pixel at a time.
Alternatively and probably better, it looks as if you can write the contents of the image to a PythonMagick.Blob object in memory, which basically does the same as writing to a file only without the file :-). You can choose what format it should write in, just as you do when writing to a file. There seems to be something called get_blob_data for extracting the contents of a Blob. Something like this:
im = PythonMagick.Image('image.jp2')
blob = PythonMagick.Blob()
im.write(blob, "png")
data = PythonMagick.get_blob_data(blob)
The resulting data is, I think, a Python string whose bytes are the binary representation of the image. (I'm assuming you're using Python 2.x, where the string type is 8-bit. I don't know whether PythonMagick works with 3.x.) I think there are some formats that are basically raw pixel data; try "RGB". You can then extract the contents via lots of struct.unpack or whatever.

Adding multiple images to one canvas in Python

I want to load a number of images from harddrive and place them on a larger white background. And I want to do it in Python. I am wondering what is the best way of doing that. I am using a windows machine and I can use any library I want. Any pointer to a webpage or a sample code that can point me to a good direction would be appreciated.
Something like this:
A very popular image processing library for Python is PIL. The official PIL tutorial might be useful, especially the section about "Cutting, Pasting and Merging Images".
PIL isn't enough. Try also with PIL the aggdraw library.
But aggdraw also isn't enough. It works poorly with transparency. I mean 0.5-1 gray pixel around opaque object over the transpparent area.

Using Python to convert color formats?

I'm working on a Python tool to convert image data into these color formats:
RGB565
RGBA5551
RGBA4444.
What's the simplest way to achieve this?
I've used the Python Imaging Library (PIL) frequently. So I know how to load an image and obtain each pixel value in RGBA8888 format. And I know how to write all the conversion code manually from that point.
Is there an easier way? Perhaps some type of 'formatter' plugin for PIL?
Does PIL already support some of the formats I'm targeting? I can't ever figure out which formats PIL really supports without digging though all of the source code.
Or is there a better library than PIL to accomplish this in Python?
Any tips would be appreciated. Thanks!
Changing something from 8 to 5 bits is trivial. In 8 bits the value is between 0 and 255, in 5 bits it's between 0 and 31, so all you need to do is divide the value with 8. Or 4 in the case for green in RGB565 mode. Or 16 in RGBA4444 mode as it uses 4 bits per channel, etc.
Edit: Reading through your question again, I think there is a confusion (either with me or you). RGB555 and RGBA4444 etc are not really formats, like GIF or JPG, they are color spaces. That conversion is trivial (see above). What file format you want to save it in later is another question. Most file formats have limited support for color spaces. I think for example that JPEG always saves it in YCbCr (but I could be mistaken), GIF uses a palette (which in turn always is RGB888, I think) etc.
There's a module called Python Colormath which provides a lot of different conversions. Highly recommended.
Numpy is powerful indeed, but to get there and back to PIL requires two memory copies. Have you tried something along the following lines?
im = Image.open('yourimage.png')
im.putdata([yourfunction(r,g,b) for (r,g,b) in im.getdata()])
This is quite fast (especially when you can use a lookup table). I am not familiar with the colour spaces you mention, but as I understand you know the conversion so implementation of yourfunction(r,g,b) should be straight forward.
Also im.convert('RGBA', matrix) might be very powerful as it is super fast in applying a colour transformation through the supplied matrix. However I have never gotten that to do what I wanted it to do... :-/
There is also a module named Grapefruit that let you do conversions between quite a lot of color formats.
I ended up doing the conversions manually as Lennart Regebro suggested.
However, pure Python (iterating over each pixel) turned out to be too slow.
My final solution used PIL to load the image and numpy to operate on (convert) an array of pixels.

Categories