g+
g+ Communities
Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014 
<== Date ==> <== Thread ==>

Subject: Re: [Scopes] BMP image record??
From: Matt Newville <newville@cars.uchicago.edu>
To: Pavel Masloff <pavel.masloff@gmail.com>
Cc: EPICS Tech Talk <tech-talk@aps.anl.gov>
Date: Mon, 30 Apr 2012 20:15:17 -0500
Hi Pavel,

On Mon, Apr 30, 2012 at 3:20 PM, Pavel Masloff <pavel.masloff@gmail.com> wrote:
> Hey Matt,
>
> Thanks for sharing! I can't make your code work, though. Every time I get
> some gibberish image, You might have forgotten to convert int to string?
> I am using the following script.
> Image file -> waveform:
>
> import Image
> import StringIO
>
> from epics import PV
> f = open('hello.bmp')  # source image file
> data = f.read()
> chan = PV ('file')
> chan.put(data)

Sorry, I think I may have misunderstood your intent.  Your script
takes the contents of the file and puts it into a waveform PV.  That's
a fine thing to do, but it is not putting the image data to the
waveform PV.  It's an interesting approach... one could do the same
with any file, as long as the consumer of the PV knows what format the
file is meant to be.

> Waveform -> image file:
>
> import os, sys
> import Image
> import StringIO
> from epics import PV
>
> chan = PV ('file')     #waveform pv
> data = chan.get()      #waveform.val
>
>
> sdata = ''.join(chr(x) for x in data)
> sfile = StringIO.StringIO(sdata)
> im = Image.open(sfile)
> im.save("yoyo.bmp")
> im.show()
>

Right - That should work, reading the waveform data as the file
contents, and interpreting it as an image file (not the data of an
image).

> Another thing I can't understand - the Intensity widget in BOY. I don't know
> how to set its properties. I set PV name, Data height, Data width, Max, Min.
> And get an ugly image.

Probably because your waveform record holds the bytes of the image
file, not the image data.

> Could you also explain to me how the trasformation image binary file ->
> waveform and back happens? As I understand an image is roughly a set of
> pixels each with its own color. There is also a header (which we don't
> need?) Then we read the file and forward every byte into the waveform record
> which is of type unsigned char (integers 0-255) with a size = 1byte. So in
> order to get an image out of the waveform we should break the waveform N
> times with an interval M (if our image dimensions are N*M). There is also a
> Color map which specifies what color our integers equal to.
> Now when we want to convert our waveform back to file we are using the
> chr(x) function, I don't know why.

Your method is definitely sending the BMP header information.  That
should be OK, but it means the consumers have to know they're getting
a BMP file, not image data.    I think that might be the issue.   You
could try something like this (untested!) to have the waveform hold
the image data:

:: Image file -> waveform:

    import Image
    import numpy as np
    from epics import PV

    chan = PV ('file')

    im = Image.open('hello.bmp')
    chan.put(im.getdata())
    # or, if that complains, perhaps
    # chan.put(np.array(im.getdata(), dtype='uint8').flatten())

That will post the image data to the waveform, and should work with
any image file, though you might have to play with the conversion
depending on what's in the image file.  The advantage is that any CA
client (say, BOY or Python) should be able to read the waveform as
image data and know what to do with it.  You might want to add a
couple auxiliary PVs where you can put the image size NX, and NY and
format (8-bit greyscale, RGBA, etc) from your Image file-> waveform
publishing script.  This is what AreaDetector does, and it allows
clients to look up the sizes and formatting without guessing.

A consumer script then might then look more like I suggested earlier:

:: Waveform -> image file:
    import Image
    from epics import PV

    chan = PV ('file')
    data = chan.get()
    im = Image.frombuffer('L', (nx, ny), data, 'raw', 'L', 0, 1)
    im.show()

    im.save("yoyo.bmp") # or 'yoyo.png', .jpg, etc

Again, you might need to carefully check the details of your bitmap
file, as bitmaps can vary, with palettes, etc.., and other formats can
have other sorts of issues.  If you assume it's 8-bit greyscale (as
'L' here does) and you get wonky looking images, you might need to
adjust that, or better yet, adjust the image you post so that the
posted data can be consumed easily as an 8-bit greyscale or RGB color
image, or whatever is appropriate.

> Next thing as you mentioned is the NELM field and EPICS_CA_MAX_ARRAY_BYTE
> variable. So if our image is say 400*300 24 bit BMP image, does it mean we
> should set NELM=400*300 and EPICS_CA_MAX_ARRAY_BYTE=400*300*24?

EPICS_CA_MAX_ARRAY_BYTES (With 'S') should exceed 400*300*3.  If you
make your 'file' PV larger than you actually need, the put() will fill
in the first part of the waveform and leave the rest untouched.  You
can count down on network traffic by asking for the appropriate size
instead of the full waveform.  Whether that matters depends, of
course.

Hope that helps,

--Matt


Replies:
Re: [Scopes] BMP image record?? Pavel Masloff
References:
[Scopes] BMP image record?? Pavel Masloff
RE: [Scopes] BMP image record?? Mark Rivers
Re: [Scopes] BMP image record?? Pavel Masloff
RE: [Scopes] BMP image record?? Mark Rivers
Re: [Scopes] BMP image record?? Pavel Masloff
RE: [Scopes] BMP image record?? Mark Rivers
Re: [Scopes] BMP image record?? Pavel Masloff
RE: [Scopes] BMP image record?? Wang Xiaoqiang
Re: [Scopes] BMP image record?? Pavel Masloff
Re: [Scopes] BMP image record?? Matt Newville
Re: [Scopes] BMP image record?? Pavel Masloff

Navigate by Date:
Prev: Re: OK to make function variable in registryFunction.c static? Andrew Johnson
Next: Re: [Scopes] BMP image record?? Pavel Masloff
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014 
Navigate by Thread:
Prev: Re: [Scopes] BMP image record?? Rod Nussbaumer
Next: Re: [Scopes] BMP image record?? Pavel Masloff
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014 
ANJ, 18 Nov 2013 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICSv4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·