how to save an array representing an image with 40 band to a .tif file

前端 未结 3 758
名媛妹妹
名媛妹妹 2020-12-21 13:02

I have an array with 600×600×40 dimension that each band(from 40 band) represent a 600×600 image I want to save it to a multiple band .tif image. I have tried this functions

3条回答
  •  南笙
    南笙 (楼主)
    2020-12-21 13:43

    You could save multiple images, each representing a single band (greyscale), or even multiple bands (colour) in a single TIFF file with PIL/Pillow like this:

    from PIL import Image
    # Synthesize 8 dummy images, all greyscale, all same size but with varying brightness
    size=(480,640)  
    b1 = Image.new('L', size, color=10)                                                         
    b2 = Image.new('L', size, color=20)                                                        
    b3 = Image.new('L', size, color=30)                                                       
    b4 = Image.new('L', size, color=40)                                                        
    b5 = Image.new('L', size, color=50)                                                        
    b6 = Image.new('L', size, color=60)                                                        
    b7 = Image.new('L', size, color=70)                                                        
    b8 = Image.new('L', size, color=80)                                                        
    
    # Save all 8 to single TIFF file
    b1.save('multi.tif', save_all=True, append_images=[b2,b3,b4,b5,b6,b7,b8]) 
    

    If you now examine that file with ImageMagick at the command line, you can see all 8 bands are present:

    magick identify multi.tif 
    multi.tif[0] TIFF 480x640 480x640+0+0 8-bit Grayscale Gray 2.34473MiB 0.000u 0:00.000
    multi.tif[1] TIFF 480x640 480x640+0+0 8-bit Grayscale Gray 2.34473MiB 0.000u 0:00.000
    multi.tif[2] TIFF 480x640 480x640+0+0 8-bit Grayscale Gray 2.34473MiB 0.000u 0:00.000
    multi.tif[3] TIFF 480x640 480x640+0+0 8-bit Grayscale Gray 2.34473MiB 0.000u 0:00.000
    multi.tif[4] TIFF 480x640 480x640+0+0 8-bit Grayscale Gray 2.34473MiB 0.000u 0:00.000
    multi.tif[5] TIFF 480x640 480x640+0+0 8-bit Grayscale Gray 2.34473MiB 0.000u 0:00.000
    multi.tif[6] TIFF 480x640 480x640+0+0 8-bit Grayscale Gray 2.34473MiB 0.000u 0:00.000
    multi.tif[7] TIFF 480x640 480x640+0+0 8-bit Grayscale Gray 2.34473MiB 0.000u 0:00.000
    

    In case you are using OpenCV or Numpy arrays for your processing, you can make an OpenCV or Numpy array into a PIL/Pillow image with:

    PILimage = Image.fromarray(numpyImage)
    

    and, going the other way, from a PIL/Pillow image to Numpy array:

    NumpyImage = np.array(PILimage)
    

    If you then want to read them back, you can do this:

    # Open the multi image
    im = Image.open('multi.tif')                                                               
    
    # Iterate through frames
    for frame in ImageSequence.Iterator(im):  
        frame.show() 
    


    If you want to move to a specific band, you can seek like this:

    im = Image.open('multi.tif')                                                               
    
    im.seek(3) 
    im.show()
    

    You can also extract band3 from the TIF and save as a PNG with ImageMagick at the command line with:

    magick multi.tif[3] band3.png
    

    Or make a band 1, 2, 7 RGB composite with:

    magick multi.tif[1] multi.tif[2] multi.tif[7] -colorspace RGB -combine 127rgb.png
    

    which will look dark blue because the red and the green channels are very low and only the blue channel has a large-ish value.


    I am not the world's best on Python, so am uncertain of any implications/errors, but I think if you have a 600x600x40 numpy array of images, you can do what I am suggesting like this:

    # Synthesize dummy array of 40 images, each 600x600
    nparr = np.random.randint(0,256,(600,600,40), dtype=np.uint8)
    
    # Make PIL/Pillow image of first
    a = Image.fromarray(nparr[:,:,0])
    
    # Save whole lot in one TIF
    a.save('multi.tif', save_all=True, append_images=[Image.fromarray(nparr[:,:,x]) for x in range(1,40)]) 
    

    Keywords: Multi-band, multi band, multi-spectral, multi spectral, satellite image, imagery, image processing, Python, Numpy, PIL, Pillow, TIFF, TIF, NDVI

提交回复
热议问题