working with raw image files

K

kafooster

I am working on some medical image data, and I try to look into
specific slice of 3d *.raw image. I know voxels are 16 bit int, and
dimensions are 352*470*96. I checked it in some pro medical image
viewer, it is alright. However, with the code I use, I display just
white noise image.(but worked well for other, 8bit raw image).
Also, printed size is half the original size, like it was 8 bit. I
read some documentations on PIL, numpy etc but I think I just do not
understand something.
I open image data set, I change it to array, give it dimensions,
dtype, and change it to image, right? I think there is something
messed up in 'binvalues', but dont really know how to write it in
simpler way.

P.S.1
If I want to change data type to e.g. 8 bit uint, is it just change in
scipy.array? or it requires some more changes

P.S.2
Lets say I have my array of image data and want to save it to *.raw
data set. is it array.tofile?

Here is my code

############################

import scipy as sc
from pylab import *
import array
import Image

fileobj = open("hand.raw", 'rb')
binvalues = array.array('B')
binvalues.read (fileobj, 352*470*96)
data1 = sc.array(binvalues, dtype=sc.int16)
data2 = sc.reshape(data1, (352,470,96))
fileobj.close()
print data2.size , data2.dtype

im = Image.fromarray(data2[:,:,40])
im.show()
 
T

Terry Reedy

I am working on some medical image data, and I try to look into
specific slice of 3d *.raw image. I know voxels are 16 bit int, and
dimensions are 352*470*96. I checked it in some pro medical image
viewer, it is alright. However, with the code I use, I display just
white noise image.(but worked well for other, 8bit raw image).
Also, printed size is half the original size, like it was 8 bit. I
read some documentations on PIL, numpy etc but I think I just do not
understand something.

You might get a better answer to such a specialized question on the
scipy list (or PIL list, if there is one) than here.
 
W

Wanderer

I am working on some medical image data, and I try to look into
specific slice of   3d  *.raw image. I know voxels are 16 bit int, and
dimensions are 352*470*96. I checked it in some pro medical image
viewer, it is alright. However, with the code I use, I display just
white noise image.(but worked well for other, 8bit raw image).
 Also, printed size is half the original size, like it was 8 bit. I
read some documentations on PIL, numpy etc but I think I just do not
understand something.
I open image data set, I change it to array, give it dimensions,
dtype, and change it to image, right? I think there is something
messed up in 'binvalues', but dont really know how to write it in
simpler way.

P.S.1
If I want to change data type to e.g. 8 bit uint, is it just change in
scipy.array? or it requires some more changes

P.S.2
Lets say I have my array of image data and want to save it to *.raw
data set. is it array.tofile?

Here is my code

############################

import scipy as sc
from pylab import *
import array
import Image

fileobj = open("hand.raw", 'rb')
binvalues = array.array('B')
binvalues.read (fileobj, 352*470*96)
data1 = sc.array(binvalues, dtype=sc.int16)
data2 = sc.reshape(data1, (352,470,96))
fileobj.close()
print data2.size , data2.dtype

im = Image.fromarray(data2[:,:,40])
im.show()

Try using numpy arrays.

import numpy as np
import Image

image1 = Image.open("hand.raw", 'rb')
imshape = image1.size
npArray = np.array(image1.getdata())
npArray.shape = imshape

im = Image.fromarray(npArray)
im.show()
 
W

Wanderer

I am working on some medical image data, and I try to look into
specific slice of   3d  *.raw image. I know voxels are 16 bit int, and
dimensions are 352*470*96. I checked it in some pro medical image
viewer, it is alright. However, with the code I use, I display just
white noise image.(but worked well for other, 8bit raw image).
 Also, printed size is half the original size, like it was 8 bit. I
read some documentations on PIL, numpy etc but I think I just do not
understand something.
I open image data set, I change it to array, give it dimensions,
dtype, and change it to image, right? I think there is something
messed up in 'binvalues', but dont really know how to write it in
simpler way.
P.S.1
If I want to change data type to e.g. 8 bit uint, is it just change in
scipy.array? or it requires some more changes
P.S.2
Lets say I have my array of image data and want to save it to *.raw
data set. is it array.tofile?
Here is my code

import scipy as sc
from pylab import *
import array
import Image
fileobj = open("hand.raw", 'rb')
binvalues = array.array('B')
binvalues.read (fileobj, 352*470*96)
data1 = sc.array(binvalues, dtype=sc.int16)
data2 = sc.reshape(data1, (352,470,96))
fileobj.close()
print data2.size , data2.dtype
im = Image.fromarray(data2[:,:,40])
im.show()

Try using numpy arrays.

import numpy as np
import Image

image1 = Image.open("hand.raw", 'rb')
imshape = image1.size
npArray = np.array(image1.getdata())
npArray.shape = imshape

im = Image.fromarray(npArray)
im.show()

P.S.1
If you want to change data size from a data buffer, you could use
something like.

image1 = np.frombuffer(Buffer, np.uint16)

P.S.2
I'm not sure what a *.raw file is but if Image has support for it you
just need to include the extension.

im = Image.fromarray(npArray)
im.save(self.resultDir + "\\" + imageName + '.tif')
 
M

MRAB

I am working on some medical image data, and I try to look into
specific slice of 3d *.raw image. I know voxels are 16 bit int, and
dimensions are 352*470*96. I checked it in some pro medical image
viewer, it is alright. However, with the code I use, I display just
white noise image.(but worked well for other, 8bit raw image).
Also, printed size is half the original size, like it was 8 bit. I
read some documentations on PIL, numpy etc but I think I just do not
understand something.
I open image data set, I change it to array, give it dimensions,
dtype, and change it to image, right? I think there is something
messed up in 'binvalues', but dont really know how to write it in
simpler way.
P.S.1
If I want to change data type to e.g. 8 bit uint, is it just change in
scipy.array? or it requires some more changes
P.S.2
Lets say I have my array of image data and want to save it to *.raw
data set. is it array.tofile?
Here is my code

import scipy as sc
from pylab import *
import array
import Image
fileobj = open("hand.raw", 'rb')
binvalues = array.array('B')
binvalues.read (fileobj, 352*470*96)
data1 = sc.array(binvalues, dtype=sc.int16)
data2 = sc.reshape(data1, (352,470,96))
fileobj.close()
print data2.size , data2.dtype
im = Image.fromarray(data2[:,:,40])
im.show()

Try using numpy arrays.

import numpy as np
import Image

image1 = Image.open("hand.raw", 'rb')
imshape = image1.size
npArray = np.array(image1.getdata())
npArray.shape = imshape

im = Image.fromarray(npArray)
im.show()

P.S.1
If you want to change data size from a data buffer, you could use
something like.

image1 = np.frombuffer(Buffer, np.uint16)

P.S.2
I'm not sure what a *.raw file is but if Image has support for it you
just need to include the extension.

im = Image.fromarray(npArray)
im.save(self.resultDir + "\\" + imageName + '.tif')
A .raw file doesn't contain a header, just the pixel values.
 
K

kafooster

Wanderer: by *.raw I mean images with .raw extension, pure pixel data
without header
http://en.wikipedia.org/wiki/Raw_image_format

That is a clear and nice code however I think Image.open cannot
handle .raw since i get error

image1 = Image.open("hand.raw", "rb")
File "D:\Python27\lib\site-packages\PIL\Image.py", line 1947, in
open
raise ValueError("bad mode")
ValueError: bad mode
 
W

Wanderer

Wanderer: by *.raw I mean images with .raw extension, pure pixel data
without headerhttp://en.wikipedia.org/wiki/Raw_image_format

That is a clear and nice code however I think Image.open cannot
handle .raw since i get error

    image1 = Image.open("hand.raw", "rb")
  File "D:\Python27\lib\site-packages\PIL\Image.py", line 1947, in
open
    raise ValueError("bad mode")
ValueError: bad mode

Try dropping the "rb". I don't use it in my code. I copied it from the
OP.
 
T

Terry Reedy

what is a .raw file, do you mean a flat binary?
Perhaps tiff-like.
https://secure.wikimedia.org/wikipedia/en/wiki/Raw_image_format

"Providing a detailed and concise description of the content of raw
files is highly problematic. There is no single raw format; formats can
be similar or radically different. Different manufacturers use their own
proprietary and typically undocumented formats, which are collectively
known as raw format. Often they also change the format from one camera
model to the next. Several major camera manufacturers, including Nikon,
Canon and Sony, encrypt portions of the file in an attempt to prevent
third-party tools from accessing them.[2]"

A real mess.

'.raw' is used (among others) by Panasonic and Leica. Not clear if .raw
is the same for both.
 
K

kafooster

Ok, I solved the problem with matplotlib

fileobj = open("hand.raw", 'rb')
data = numpy.fromfile(fileobj,dtype=np.uint16)
data = numpy.reshape(data,(96,470,352))
imshow(data[:,:,40],cmap='gray')
show()

the error was caused by different order of data, however it still
reads the dataset as half of it size. whatever.

please leave the part about .raw, lets just start thinking of it from
level of numpy array.

I would like to visualize this data with PIL, but PIL works only with
8bit data. How could I resample my array from 16bit to 8bit?
 
M

MRAB

Ok, I solved the problem with matplotlib

fileobj = open("hand.raw", 'rb')
data = numpy.fromfile(fileobj,dtype=np.uint16)
data = numpy.reshape(data,(96,470,352))
imshow(data[:,:,40],cmap='gray')
show()

the error was caused by different order of data, however it still
reads the dataset as half of it size. whatever.

please leave the part about .raw, lets just start thinking of it from
level of numpy array.

I would like to visualize this data with PIL, but PIL works only with
8bit data. How could I resample my array from 16bit to 8bit?

Multiply the numpy array by a scaling factor, which is
float(max_8bit_value) / float(max_16bit_value).
 
K

kafooster

Multiply the numpy array by a scaling factor, which is
float(max_8bit_value) / float(max_16bit_value).

could you please explain it a little? I dont understand it. like
multiplying each element?
 
M

MRAB

could you please explain it a little? I dont understand it. like
multiplying each element?

Yes. Something like this:

fileobj = open("hand.raw", 'rb')
data = numpy.fromfile(fileobj, dtype=numpy.uint16)
fileobj.close()
data = data * float(0xFF) / float(0xFFFF)
data = numpy.array(data, dtype=numpy.uint8)
data = data.reshape((96, 470, 352))
imshow(data[:, :, 40], cmap='gray')
show()
 
D

Dave Angel

could you please explain it a little? I dont understand it. like
multiplying each element?

You said in an earlier message to ignore the RAW format. However, if
your file matches a typical camera's raw file, there are several problems:

1) the data is typically 12 to 14 bits per pixel, only rarely 16 (very
expensive cameras)
2) the data does not have R, G and B values for each pixel, but only one
of these. The others are generated by Bayer interpolation.
3) the data is linear (which is what the hardware produces), and
traditional image data wants to be in some non-linear color space. For
example, most jpegs are sRGB 8*3 bits per pixel.

The first would mean that you'd need to do a lot of shifting and
masking. The second would mean a pretty complex interpolation
algorithm. And the third would require an exponential function at the
very least.

DaveA
 
K

kafooster

Yes. Something like this:

fileobj = open("hand.raw", 'rb')
data = numpy.fromfile(fileobj, dtype=numpy.uint16)
fileobj.close()
data = data * float(0xFF) / float(0xFFFF)
data = numpy.array(data, dtype=numpy.uint8)
data = data.reshape((96, 470, 352))
imshow(data[:, :, 40], cmap='gray')
show()

thank you very much, it works and now I can display this data even
with Image.fromarray(). As I understand, it multiplies data elements
by a fraction, so that when we have less levels (in 8uint), it can fit
there?
 
K

kafooster

You said in an earlier message to ignore the RAW format.  However, if
your file matches a typical camera's raw file, there are several problems:

1) the data is typically 12 to 14 bits per pixel, only rarely 16 (very
expensive cameras)
2) the data does not have R, G and B values for each pixel, but only one
of these.  The others are generated by Bayer interpolation.
3) the data is linear (which is what the hardware produces), and
traditional image data wants to be in some non-linear color space.  For
example, most jpegs are sRGB 8*3 bits per pixel.

The first would mean that you'd need to do a lot of shifting and
masking.  The second would mean a pretty complex interpolation
algorithm.  And the third would require an exponential function at the
very least.

DaveA

well, I am only working with grayscale MRI medical images(mainly 8 or
16bits), saved as .raw. I do not need to worry about rgb.
 
M

MRAB

Yes. Something like this:

fileobj = open("hand.raw", 'rb')
data = numpy.fromfile(fileobj, dtype=numpy.uint16)
fileobj.close()
data = data * float(0xFF) / float(0xFFFF)
data = numpy.array(data, dtype=numpy.uint8)
data = data.reshape((96, 470, 352))
imshow(data[:, :, 40], cmap='gray')
show()

thank you very much, it works and now I can display this data even
with Image.fromarray(). As I understand, it multiplies data elements
by a fraction, so that when we have less levels (in 8uint), it can fit
there?

Correct.
 
N

Nobody

You said in an earlier message to ignore the RAW format. However, if
your file matches a typical camera's raw file

It doesn't. He's dealing with a raw array of fixed-size integers (i.e.
what you would get if you took a C array and wrote the memory directly to
a file).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,710
Latest member
bernietqt

Latest Threads

Top