Spectral Python (SPy)的学习笔记(2)数据读取

使用SPy打开和访问高光谱图像文件的标准方法是通过图像函数,它返回一个SpyFile对象的实例。

SpyFile界面

SpyFile是创建读取高光谱数据文件的对象的基类。 当创建一个SpyFile对象时,它提供了一个从相应的文件中读取数据的接口。 打开图像时,返回的实际对象将是SpyFile(BipFile,BilFile或BsqFile)的子类,与图像文件中的数据交错相对应。
让我们打开我们的示例图像。

In [1]: from spectral import *
In [2]: img = open_image('92AV3C.lan')
In [3]: img.__class__
Out[3]: spectral.io.bilfile.BilFile

In [4]: print img
	Data Source:   '/home/thomas/spectral_data/92AV3C.lan'
	# Rows:            145
	# Samples:         145
	# Bands:           220
	Interleave:        BIL
	Quantization:  16 bits
	Data format:     int16

该图像不在工作目录中,但仍处于打开状态,因为它位于SPECTRAL_DATA环境变量指定的目录中。 由于图像像素数据是按行交错的,图像函数返回了一个BilFile实例。
由于高光谱图像文件可能相当大,只有在SpyFile对象第一次创建时才从文件中读取元数据。 图像数据值只有在通过SpyFile方法特别要求时才能读取。 SpyFile类提供了一个下标运算符,其行为与numpy数组下标运算符非常相似。 SpyFile对象被下标为MxNxB数组,其中M是图像中的行数,N是列数,B是带的数量。

In [5]: img.shape
Out[5]: (145, 145, 220)

In [6]: pixel = img[50,100]

In [7]: pixel.shape
Out[7]: (220,)

In [8]: band6 = img[:,:,5]

In [9]: band6.shape
Out[9]: (145, 145, 1)

在执行下标运算符调用之前,不从文件中读取图像数据值。 请注意,由于Python索引从0开始,因此img [50,100]指的是图像的第51行和第101列的像素。 同样的,img [:,:,5]是指图像第6条带的所有行和列。
为特定图像文件返回的SpyFile子类实例也将提供以下方法

SpyFile对象有一个band成员,它是一个BandInfo对象的实例,它包含有关图像光谱波段的可选信息。

加载整个图像

需要注意的是,图像数据被SpyFile对象按需读取,并且数据不被缓存。每次调用SpyFile下标操作符或其中一个SpyFile读取方法时,都会从相应的图像数据文件中读取数据,而不管之前是否读取过相同的数据。这样做是为了避免在处理非常大的图像文件时消耗太多内存。 当执行只需要读取大图像中的一小部分数据(例如,读取RGB带以显示图像)的操作时,它也提高了性能。按需读取数据而不缓存数据的缺点是,运行需要访问所有数据的算法时可能会产生严重的运行时间损失。 如果算法需要对数据进行迭代访问,性能会更差。

为了提高光谱算法的性能,最好使用load方法将整个图像加载到内存中,该方法返回一个ImageArray对象。ImageArray提供了完整的numpy.ndarray接口,以及SpyFile接口 。

In [1]: arr = img.load()

In [2]: arr.__class__
Out[2]: spectral.spectral.ImageArray

In [3]: print arr.info()
	# Rows:            145
	# Samples:         145
	# Bands:           220
	Data format:   float32

In [4]: arr.shape
Out[4]: (145, 145, 220)

由于SPy主要设计用于在光谱范围内进行处理,因此无论源图像数据文件的交错如何,内存中的spectral.ImageArray对象都将始终按像素交织数据。换句话说,numpy.ndarray形状将是(numRows,numCols,numBands)。 ImageArray对象始终包含32位浮点数

注意:

在调用load方法之前,重要的是要考虑生成的ImageArray对象将要消耗的内存量。由于spectral.ImageArray使用32位浮点值,因此消耗的内存量大约为4 * numRows * numCols * numBands个字节

NumPymemmap Interface

作为将整个图像加载到内存中的一种替代方法,访问图像数据的速度稍慢(但更具有内存效率)是使用numpy memmap对象,由SpyFile对象的open_memmap方法返回。也可以使用memmap对象将日期写入图像文件。

文件格式支持
ENVI头文件
ENVI [1]是一个流行的商业软件包,用于处理和分析地理空间图像。 SPy可以读取具有相关ENVI头文件的图像,并可以使用ENVI头读取和写入光谱库。ENVI文件由SPy图像功能自动打开,但图像也可以作为ENVI文件显式打开。 如果数据文件位于标题的单独目录中,或者数据文件具有SPy无法识别的异常文件扩展名,则可能需要明确打开ENVI文件。

In [5]: import spectral.io.envi as envi

In [6]: img = envi.open('cup95eff.int.hdr', 'cup95eff.int')

In [7]: import spectral.io.envi as envi

In [8]: lib = envi.open('spectra.hdr')

In [9]: lib.names[:5]
Out[9]: 
[u'construction asphalt',
 u'construction  concrete',
 u'red smooth-faced brick',
 u'weathered red brick',
 u'bare red brick']

另请参见将图像数据写入文件的功能:
create_image:在磁盘上创建一个分配有存储空间的新映像文件。
save image:将现有的图像或ndarray保存到具有ENVI标头的文件中。

AVIRIS数据

SPy支持由机载可视/红外成像光谱仪(AVIRIS)生成的数据文件[2]。AVIRIS文件由open_image函数自动识别; 但是,光谱波段校准文件不能被自动识别; 因此您可能需要将图像作为AVIRIS文件显式打开并指定cal文件。

In [10]: img = aviris.open('f970619t01p02_r02_sc01.a.rfl', 'f970619t01p02_r02.a.spc')

您也可以单独加载波段校准文件(如果波段校准文件是AVIRIS格式,但图像不是这样,则可能需要这样做)。

In [11]: img = open_image('92AV3C.lan')

In [12]: img.bands = aviris.read_aviris_bands('92AV3C.spc')

ERDAS/Lan数据

ERDAS / Lan文件格式是由图像自动识别的。 一个文件不太可能需要作为一个Lan文件明确打开,但可以按如下方式完成。

In [13]: import spectral.io.erdas as erdas

In [14]: img = erdas.open('92AV3C.lan')

参考文献

[1]ENVI is a registered trademark of Exelis Visual Information Solutions.
[2]http://aviris.jpl.nasa.gov/







  • 4
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值