Saturday, 31 December 2011

Opening multispectral or hyperspectral ENVI files in MATLAB


ENVI/IDL is one of the most used remote sensing software package which has a nice programming interface known as IDL. Though I have been using IDL for quite some time now, I still prefer MATLAB over IDL because MATLAB has extensive help documentation with lots of useful demonstration which I think is lacking in IDL.

There is a function in MATLAB which not many people are aware of, which is called Multibandread. Multibandread can be use for any type of binary files such as bsq, bil and bip. As long as you know how the data is organized in the binary file, its data type, rows columns and no. of bands in the file you can read the file in MATLAB with Multibandread.  Multibandread requires following informations.

X = multibandread(filename, size, precision, offset, interleave, byteorder)

With ENVI files, you can find all these information in the header file of that ENVI file. Using that information, you can pass this information by manually typing or you can write a custom function which will open the header file, fetch those information from the header file and pass it to Multibandread. I usally do it with latter approach.
Opening whole remote sensing images in MATLAB is a bit tricky. Consider you have a hyperspectral data with 116 bands and you try to read whole image at one go. MATLAB will run out of memory. The wise thing is to read the image in a block by block (MxN), performing required operation in the block and later combining all blocks. 

One cautionary note, I have seen people doing some silly mistakes such as reading an ENVI file with 10 bands in a variable (image) and using imshow (image) to visualize it. They spend countless hours wondering why the Multibandread is not being able read their ENVI files. But they forget that imshow function can display only three band one time. So if you want to view first three band then you have to use

  Imshow( image(:,:,1:3),[])

So, try Multibandread function if you are MATLAB savvy person and prefer MATLAB over IDL.
If you run into any kind of problem, I am ready for help.

24 comments:

  1. hello!
    maby you can help me,
    i'm trying to open envi file with the multibandread and it's dosn't work...
    my function was writen like here acording to the header file:

    >> X = multibandread('cat_1_ref.bsq',[400,400,121] , 'float', 0, 'bsq', 'ieee-le',{'Band','Direct',[11,31,51]});

    do you have any clue why i'm not succeed to open the file??
    thanks!
    Michael

    ReplyDelete
  2. hello michi,

    it would be helpful if you give error information that u got in matlab.

    Nevetheless, if your hyperspectral data is in envi format, there should not be ".bsq" in file name. Try with

    X = multibandread('cat_1_ref',[400,400,121] , 'float', 0, 'bsq', 'ieee-le',{'Band','Direct',[11,31,51]});

    let me know if it works, otherwise show me what error you got!

    ReplyDelete
  3. Hello

    What do you suggest to do, if my ENVI file order is not 0 or 1 but 2? I tried as 'ieee-be' but it did not work out

    ReplyDelete
  4. hallo rashard,
    it is strange that ur header file shows that file order is 2 ? what kinda image/file is that? R u sure you are not mistaking in size parameter ?

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. Hello, I am trying to read in a hyperspectral 190 bands AVIRIS imagery as following information:
    samples = 400; lines = 400; bands = 190;
    header offset =0; datatype=2; interleave=bip; byte order=0

    I applied following code segments to visualize RGB of the image but the resulting colors of the image were not quite right (whole image was like masked with green).


    code:

    X = multibandread('atmos_corr_subset.bip', [400,400,190], 'int16', 0, 'bip', 'ieee-le',{'Band','Direct',[29,11,20]});

    imshow (X)

    Is there any way to fix it. Thanks.

    ReplyDelete
  8. Hi pewxat,
    After reading, your X matrix would be size(400x400x3).

    Make sure first data you have read is properly read.

    Display individual band first.
    imshow(X(:,:,1),[]).

    putting [] in imshow will strech your data to min max for better visualization.

    if every band is properly read, then use
    imshow(X,[]).

    ReplyDelete
    Replies
    1. Thanks, I successfully load the image, actually the problem is that I need normalized the data so the there is not negative value in the matrix, otherwise the matlab cannot read it. Thanks anyway for your response.

      Delete
  9. Hello!! My name is Raghuram. I'm, trying to load a hyperspectral image using multibandread, but I am unable to do so. I'm getting the following errors.

    ??? Error using ==> multibandread>parseInputs at 316
    Unable to open QuAC.bsq for reading.

    Error in ==> multibandread at 108
    info = parseInputs(filename, dims,...

    Error in ==> read_hyperim at 4
    I = multibandread('QuAC.bsq',[3191 911 196],'int16','0','bsq','ieee-le',...

    Is matlab unable to locate the file to be read? How do I rectify this?
    Thank you!!

    ReplyDelete
  10. hallo raghuram,
    sorry for delay answer. I was away for a while.

    The problem might be because of any of the following two reason.

    1) Either your file is not in the current dir. Use full path if the file is in some other location.
    2) the dimension you provided might not be correct. Remember that ENVI uses samples( column) and line (row) format whereas Matlab uses row and column. In addition you dimension information should be [3191,911,196] with comma in between.

    ReplyDelete
  11. I did manage to load the image. If I have to perform classification using supervised or unsupervised techniques, how do I use the blockproc function in matlab to do this?

    ReplyDelete
  12. This comment has been removed by the author.

    ReplyDelete
  13. If you be more specific on which supervised or unsupervised classification you intend to do, i may be help. I use blockpro, if my image is too big to fit into matlab's memory and i access chunk of data by using custom adapter. Search Lan Adapter in MATLAB, you will get the idea.

    ReplyDelete
  14. Hello,
    I am trying to open mult-band image in Matlab but no luck till now. Below is the Matlab code

    multibandread('can_tmr.img',[400,640, 6],'float',0,'bsq','ieee-le',{'Band','Direct',[4 3 2]});

    The error matlab gives is
    Error using ==> multibandread at 119
    The file is too small to contain the specified data.Check the size, offset, and precision arguments.


    Here is header information of the imagery
    samples = 640
    lines = 400
    bands = 6
    header offset = 0
    file type = ENVI Standard
    data type = 1
    interleave = bsq
    sensor type = Unknown
    byte order = 0

    ReplyDelete
  15. sir i have seperate image for each band i want to combine it in single image then how should i?
    & hw to knw the info abot whether it is bil or bsq..etc plz hel me out

    ReplyDelete
    Replies
    1. hi priyanka,
      sorry replying late. If you successfully opened your image in matlab, then you could easily combine it.
      b1=imread(.....)
      b2=imread(.....)
      b3=imread(.....)

      combine image= zeros(size(b1),3 )
      combine image(:,:,1) = b1;
      combine image(:,:,2) = b2;
      combine image(:,:,3) = b3;

      Then save your combine image with imwrite function.

      If you want to do it in ENVI then shoot me an email, i let you know how to do it. There is a way to do it if you want to do it in GIS environment.

      Delete
    2. Hello Shreshai

      Thanks for such useful information.
      I tried it and I am able to read 3 bands at a time
      (coz if I read all 360 bands than its showing out of memory)

      but I am able to display it properly, I mean imshow(:;:;1:3,[]) is working but it is showing just colored waves ...not a meaningful picture as seen in ENVI display.
      Please help !!

      Delete
  16. Hi Deepti,
    Reading a whole hyperspectral image in matlab is still problematic due to memory limitation in MATLAB. Get a good machine with higher memory 16 or 32 GB and move to 64 bit architecture. If you dont have luxury of moving to better machine you can try to open in block by block. This can be done. Shoot me an email i will give out the code to do that. In that first you have to define an image adapter that will work in tandem with blkproc function in matlab.

    Regarding your problem, i think you failed to open your image in matlab properly. So it has do with your input parameter r, c, and byte order etc. Just visualize your image just one band, and see if you can see something meaningful. Otherwise you are not reading your file properly.

    if you are willing to send me your data (small) i can have a look.

    I have moved to wordpress. Please visit http://geotipsandtricks.wordpress.com/ for more recent blogs.

    thanks
    shailesh

    ReplyDelete
  17. Sir, is possible to interface the ENVI with matlab? because i have pre-processing matlab codes which i want to directly interface into the ENVI for further processing. Sir also i want to know, is possible to convert Matlab Codes into IDL codes?

    ReplyDelete
  18. Sir I am Using the hyperion data with L1R extension I am not getting how to choose the file name for multibandread command to load the hyperspectral image.

    ReplyDelete
  19. Sir I have done preprocessing of hyperioni data now I want to load my flash image and all the bands into matlab so DAT I can perform data reduction plz help me to do same

    ReplyDelete
  20. Sir I have done preprocessing of hyperioni data now I want to load my flash image and all the bands into matlab so DAT I can perform data reduction plz help me to do same

    ReplyDelete
  21. This comment has been removed by the author.

    ReplyDelete