Image to array

Is there an easy way to read in an image (JPEG, GIF, BMP, whatever…) and get the actual pixel information out in an array or histogram? For example, if I have a 400x300 grayscale BMP, can I read it in and output the pixel grayscale data into an array or TH2F (I’d like to do this so I can do some processing and fitting on the image data).

jesse wodin

May be what you are looking for is the TASImage library:

root.cern.ch/root/htmldoc/TASImage.html

Just a suggestion…

Cheers, Olivier

TASImage doesn’t seem to be able to dump to histograms…

jesse

I think MatLab might be useful for the job!

I just finished doing this exact thing.

First convert the image to ascii format. I used Imagemagick, but you could also use GIMP or some other free tool. Then write a script to read in the image data to your histogram. Imagemagick produces the following ascii format:

row,column: Red, Green, Blue, Hex Color

So I wrote:

while(1){
in.getline(tempx,16,’,’);
x = atoi(tempx);
in.getline(tempy,16,’:’);
y = atoi(tempy);
in.getline(tempz,16,’,’);
z = atoi(tempz);
in.getline(trash,256);
if (!in.good()) break;
dat->Fill(x,y,z);
tree->Fill();
nlines++;
}

where dat and tree were previously set up as a TH2F histogram and a TTree.

Tom

With ROOT Qt layer (http:root.bnl.gov) it is easy

For each TPad Qt layer creates the QPixmap obect
doc.trolltech.com/3.3/qpixmap.html

that your can access from your code

root.bnl.gov/QtRoot/QtRoot.html#qt

[quote=“jwodin”]TASImage doesn’t seem to be able to dump to histograms…

jesse[/quote]

This may help you also

root.bnl.gov/QtRoot/QtRoot.html#gifbatch

Hi,
now implemented. Must be in CVS today.
Here is a CVS log

Regards. Valeriy

[quote=“Valeriy Onuchin”]Hi,
now implemented. Must be in CVS today.
Here is a CVS log

Regards. Valeriy[/quote]

Does this mean the TImage class has TH2 class dependency :unamused:

Hi Valera,
not TImage, but TASImage - yes.

Regards. Balepa

[quote=“Valeriy Onuchin”]Hi Valera,
not TImage, but TASImage - yes.

Regards. Balepa[/quote]

It seems to me I am completely lost with the current design.

I thought the TImage class is an abstract interface
(see:http://root.cern.ch/root/htmldoc/TImage.html) the user works with and TASImage is that interface implementation loaded with ROOT plugin.

Is it still correct?

Anyway the TH2 class dependency of the “image” class is wierd.

Hi Valeri,
as I said TImage doesn’t depend on TH2.
Both TH2 related methods are not abstract.
It’s up to you to implement them or not.
BTW, TImage is a part of libGraph library
which already depends on libHist (say TH2).

Regards. Valeriy

Hi Valeri,
… yes …
there is some descripency in dependency of TImage class.
We will try to find better solution. Do you have ideas?

Thanks. Regards. Valeriy

[quote=“Valeriy Onuchin”]Hi Valeri,
… yes …
there is some descripency in dependency of TImage class.
We will try to find better solution. Do you have ideas?

Thanks. Regards. Valeriy[/quote]

I did not understand the question.
Idea about what? How to save the TPad in the “pixel” format?

Hi Valeri,
the idea is about "how to organize all in the better way"
It looks like that TImage class must be in the “base” …
not in the graf. Recently I made wrong addons making it
dependent on TGPicture and TH2. For a moment TH2
dependency could be forgiven because graf itself depends on TH2.

What is your opinion how to organaize it in the best way?

Regards. Valeriy

Hmm, first you did something odd then you are asking me about the “best way”. I have no such luxury. All my ROOT contributiond had to be approved first by many “commitee”.

Anyway, What is wrong you find with the solution I have posted several times (including this thread):

root.bnl.gov/QtRoot/QtRoot.html#gifbatch

I mean TVirtualX had provided a generic interface (even several ones) to create the file for any TPad. Why are you introducing another interface to manage 2D histograms only?

What about the implementation of TVirtualX, there you are free to provide any solution for x11/win32gdk etc. Qt layer aready did it. If you think this is wrong tell me to fix.

Hi,
Actually it is the answer on the original question: is there an easy way to read for example BMP image into the array.

The below function do the job. This function is in principle a part of class, we use for storage and processing images. It could be posted if have general interst. Of cause root is not the best tool for image processing, but sometimes it could be convenient for the small samples.

VT

//____________________________________________________________________________________
Int_t EdbImage::LoadBMP( char file )
{
/

Loads a BMP format file…
/
typedef struct {
unsigned short int type; /
Magic identifier /
unsigned int size; /
File size in bytes /
unsigned short int reserved1, reserved2;
unsigned int offset; /
Offset to image data, bytes */
} HEADER;

typedef struct {
unsigned int size; /* Header size in bytes /
int width,height; /
Width and height of image /
unsigned short int planes; /
Number of colour planes /
unsigned short int bits; /
Bits per pixel /
unsigned int compression; /
Compression type /
unsigned int imagesize; /
Image size in bytes /
int xresolution,yresolution; /
Pixels per meter /
unsigned int ncolours; /
Number of colours /
unsigned int importantcolours; /
Important colours */
} INFOHEADER;

HEADER hdr;
INFOHEADER ihdr;

//printf(“hdr: %d ihdr: %dn”,sizeof(hdr), sizeof(ihdr));
char* ptr;
fstream raw(file,ios::in | ios::binary);
ptr=(char*)&hdr;
raw.read(ptr,14);
ptr=(char*)&ihdr;
raw.read(ptr,40);
if(ihdr.bits!=8) { printf(“Error: %d bits/pixel bitmap is not supported!n”,ihdr.bits); return -1;}
int N=ihdr.widthihdr.height;
char
byte= new char[N];
raw.read(byte,1024);
raw.read(byte,N);
raw.close();
eBytes=N;
eColumns=ihdr.width;
eRows=ihdr.height;
eColors=256;

eBuffer->Adopt(eBytes,byte);

printf(“EdbImage::LoadBMP: file %s is readed…Image %d x %d pixels.n”, file,eColumns,eRows);

return N;
}

Thank you very much your example.

However the whole idea of C++ framework is to hide the concrete implementation to make the consumer code free of the concrete image format details.

Writting code that manipulate with the pixel information one should not worry about the file format those pixels were read from
(will be stored in )

I think we want to apply the solution that doesn’t requires us to change our code each time the input format changed.

See for example the class

doc.trolltech.com/3.3/qimage.html

I think it much simple to apply
doc.trolltech.com/3.3/qimage.html#QImage-4

QImage in(“myImagefile.bmp”)

and then work with pixel information using different convinient interfaces like:

doc.trolltech.com/3.3/qimage.html#bits
doc.trolltech.com/3.3/qimage.html#scanLine
doc.trolltech.com/3.3/qimage.html#jumpTable

Of course at some low level there is the code like that you mentioned.

On the other hand that code should not have any idea how the pixel will be treated by the higher level code.

By this reason I would not encourace anybody except those with the very special needs to apply your solution.

I think what one needs is to set of the methods for ROOT TImage class root.cern.ch/root/htmldoc/TImage.html to provide the functionality of QImage

Hi,
I’m actively working on TImage/TASImage right now.
I have to finish with it before Christmass release.
That will provide requested functionality, i.e.
image -> array, array -> image etc. ++ “gifbatch” and
much more.

Regards. Valeriy


Have you any intention to change the the high-lebel interface.
(in the other words TImage class methods and signatures) ?

The main question whether it is will, backward compatible or we will forcve us to redesigg our applications once again?

My believe the new feature must not panish the old ROOT users and make thier life more troublesome.