Getting pixel data from a PythonMagick image? - python

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.

Related

Python: Tensorflow PNG encoding

I'm trying to figure out the reason, why this code snippet returns False:
decodedBase64 = tf.io.decode_base64(imgBase64)
decodedBase64==tf.io.encode_png(tf.io.decode_png(decodedBase64))
A png image can be compressed and decode_png detects it, so I used different 'compression=' values in encode_png. I still got False with all values between -1 to 9.
What can be done to retrieve correct decodedBase64 characteristics to make encode_png <-> decode_png reversible?
I am not very familiar with tensorflow and your code is not runnable to be able to try it, so I may well be wrong and will delete my answer if so. I also think that the base64 encoding and decoding is something of a red herring. I think you are actually asking why you get a different PNG from one you already have when you encode with tensorflow. If so, there are several possible reasons:
the date and time may be encoded in the PNG so if you write a PNG and then write it again with the same compression 1 second later, it will differ if that is the case
the original PNG might have been created with a different library, a different version or different parameters, and although you will get the same pixels back because the encoding is lossless, the encoded data on disk could differ. For example, one library might choose a different filter for some rows - or no filter at all
Of course, if you want a definitive rather than speculative answer, you'd need to share the 2 PNGs - unmodified.

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

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.

what is the as3 bitmapdata bytearray format / how to transform into png in python

in a local as3 application i need to capture a video at 25 frames per second and send the bytearray to a local python script.
when i try to encode the bytearray to png inside as3 it is much to slow.
so i decided to just write the raw bytearray i got from :
var bitmapdata:BitmapData = new BitmapData(_videow,_videoh,false,0);
bitmapdata.draw(_video);
var ba:ByteArray=bitmapdata.getPixels(bitmapdata.rect);
this is pretty performant and does not drop frames so far.
however, i need to convert these raw bytes to png on the python side.
any idea how i can achieve that?
thanks!
It's roughly the same as PCX* (some earlier variant of BMP). It is actually very similar to BMP, save that there are no headers, and the pixels are written from left to right, top down ARGB for transparent bitmapdata and RGB for solid.
What PNG encoder did you use? Have you tried this one: http://www.blooddy.by/en/crypto/ ? Of course, Python may be using GD / Imagemagic behind the scenes, so, obviously C code would be faster, but if you wanted it to run on the user's PC, then I'd give this a try.
PS: http://www.senocular.com/flash/actionscript/?file=ActionScript_3.0/com/senocular/images/BMPEncoder.as this may give some insights, as it is converting bitmapdata into BMP.
Sorry, that's not a PCX, I've confused PCX to something else, it's just a variant of BMP, with a different pixel ordering.

How to extract a given frame from a .gif animation in Python

I'm trying to figure out how to extract a given frame from an animated-gif, possibly in PIL, in Python.
I'm not able to easily dig this up, and I'm guessing it would take some knowledge of the gif format, something that is not readily understandable to me.
Is there any straightforward way to accomplish this? Do I need to do some custom parsing?
Reading Sequences
The GIF loader supports the seek and
tell methods. You can seek to the next
frame (im.seek(im.tell()+1), or rewind
the file by seeking to the first
frame. Random access is not supported.
http://effbot.org/imagingbook/format-gif.htm
http://effbot.org/imagingbook/image.htm

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