2

I want to load hyperspectral data per pixel into an array and write this pixel out again using Python 3.5. I want to calculate something with the spectral information of this Pixel.

I have tried two different ways and both don't work the way I want.

First of all I have updated spectral package since the last version was stated not to work with iteratively envi.save_image but still my approach does not work. Second my approaches both are not very good with my double for loop - I know - If anyone could please help me on my problem.

1st:

myfile=open_image('input.hdr')
    for i in range(0,myfile.shape[0]):
        for j in range(0,myfile.shape[1]):
            mypixel = (myfile.read_pixel(i,j))
            envi.save_image('output.hdr', mypixel, dtype=np.int16)

1st example does not save the image rather gives me the error code

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.5/site-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 699, in runfile
execfile(filename, namespace)
File "/usr/local/lib/python3.5/site-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 88, in execfile
exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace)
File "/dtc/Python/Masking.py", line 132, in <module>
envi.save_image('test.hdr', mypixel, dtype=np.int16)#, metadata=myfile.metadata)
File "/usr/local/lib/python3.5/site-packages/spectral/io/envi.py", line 415, in save_image
data, metadata = _prepared_data_and_metadata(hdr_file, image, **kwargs)
File "/usr/local/lib/python3.5/site-packages/spectral/io/envi.py", line 568, in _prepared_data_and_metadata
add_image_info_to_metadata(image, metadata)
File "/usr/local/lib/python3.5/site-packages/spectral/io/envi.py", line 613, in add_image_info_to_metadata
metadata['samples'] = image.shape[1]
IndexError: tuple index out of range 

2nd:

myfile=open_image('input.hdr')
envi.create_image('test.hdr',ext='.bip', interleave='bip',dtype='h',force=True,metadata=myfile.metadata)
open('test.bip', 'w').close() # empties the  created file

file = open('test.bip', 'ab')#ab #opens the created file for appending the new bands

for i in range(0,myfile.shape[0]):
    for j in range(0,myfile.shape[1]):
        mypixel = (myfile.read_pixel(i,j))
        file.write(mypixel) 
file.close()
myfile.close()

The second example saves the image but stores the Pixel in a different order and messes up my image.

bogatron
  • 18,639
  • 6
  • 53
  • 47
AnneR
  • 31
  • 5

2 Answers2

1

So this is the very short, fast and easy solution thanks to a colleague.

myfile=envi.open('input.hdr') #opens image for calculating with it

    imageArray = 10000*myfile[:,:,:] #do some math with it; 

    #10000* is needed because input data are thresholded between {0;10000} 
    #and during processing get thresholded between {0;1}. 
    #For preventing 0 in the output with datatype int the thresholding to {0;10000} is necessary again

envi.save_image('test.hdr',imageArray,dtype=np.int16,metadata=myfile.metadata,force=True)
AnneR
  • 31
  • 5
-1

I have to say in advance that I am not familiar with the spectral package and envi and therefore unfortunately cannot offer a ready-to-use solution. Besides, I am not sure if I correctly understood what you are trying to do with your image.

But just some thoughts: Could the write/save function inside the for loop cause your problem, because every pixel is treated in the exact same way and it gets overwritten? I can not relate to the IndexError though.

Maybe you need a function where you can rather write a certain pixel to an empty image passing also i and j. A second option could be to save each pixel in an array and save it to an image at once after the for loop.

AriJane
  • 9
  • 4
  • Thank you for your answer. I have tried this and also got this hint from colleagues. This worked and was faster in the end. Still didn't give me the results I expected. The output is an image with only zero data. – AnneR May 18 '16 at 07:37