立即掃碼咨詢
聯(lián)系方式:010-51292601
聯(lián)系我們時(shí)請(qǐng)說(shuō)明在儀器網(wǎng)(m.sdczts.cn)上看到的!
近年來(lái),深度學(xué)習(xí)和大數(shù)據(jù)處理技術(shù)為高光譜分析帶來(lái)了巨大的變革,使用深度學(xué)習(xí)處理高光譜數(shù)據(jù)已經(jīng)成為研究的主流熱點(diǎn)。ENVI提供了成熟高效的高光譜處理平臺(tái),但是相對(duì)穩(wěn)定的軟件結(jié)構(gòu)降低了應(yīng)用的靈活性。而且ENVI對(duì)于流行的深度學(xué)習(xí)架構(gòu)支持不夠完善,難以滿足現(xiàn)在復(fù)雜的研究需要。本文將介紹使用Python處理高光譜數(shù)據(jù)的思路,并提供相關(guān)代碼方便讀者復(fù)現(xiàn)。
Python
Python是一門(mén)計(jì)算機(jī)語(yǔ)言。編程人員通過(guò)編寫(xiě)Python代碼命令計(jì)算機(jī)執(zhí)行指令,完成特定的任務(wù)。編寫(xiě)代碼時(shí)需要遵循Python獨(dú)特的風(fēng)格,Python內(nèi)部才能正確將這些代碼轉(zhuǎn)換為計(jì)算機(jī)可以理解的指令。Python有著非?;钴S的社區(qū),一般問(wèn)題都能通過(guò)搜索引擎找到答案,這大大提高了使用Python進(jìn)行編程的效率。
由于其簡(jiǎn)單開(kāi)放的特性,Python受到科學(xué)界的廣泛支持,成為科研工作中Z 流行的語(yǔ)言。Python本身不具備科學(xué)計(jì)算的能力,而且運(yùn)行效率較低。為此,科學(xué)家和工程師開(kāi)發(fā)了完整的基于Python的科學(xué)計(jì)算生態(tài)系統(tǒng)。該生態(tài)系統(tǒng)包括矩陣庫(kù)Numpy、表格庫(kù)Pandas、科學(xué)計(jì)算庫(kù)Scipy、繪圖庫(kù)Matplotlib以及代碼編輯運(yùn)行工具Jupyter等工具包。這些工具包不僅降低了使用Python進(jìn)行科學(xué)計(jì)算的門(mén)檻,還通過(guò)底層優(yōu)化,大大提高了運(yùn)算速度。所以在使用Python進(jìn)行高光譜圖像進(jìn)行處理時(shí)要同時(shí)學(xué)習(xí)這些工具,學(xué)習(xí)的優(yōu)先級(jí)和掌握程度參考右圖。

光譜庫(kù)文件的讀取
Python獨(dú)立安裝包內(nèi)不包含科學(xué)計(jì)算的工具包,且需要繁瑣的步驟進(jìn)行開(kāi)發(fā)環(huán)境的配置,所以推薦使用Anaconda進(jìn)行Python程序的安裝。Anaconda中包含了大部分科學(xué)計(jì)算工具,可以快速搭建高光譜數(shù)據(jù)處理平臺(tái)。

下載地址:https://www.anaconda.com/products/individual
安裝完成后重啟。
打開(kāi) Anaconda Prompt Shell,輸入以下命令,將目錄切換到工作目錄下,運(yùn)行 Jupyter Lab,并依次點(diǎn)擊 File -> New -> Notebook 新建文件:

將ASCII格式的光譜庫(kù)文件拷貝到工作目錄下。
首先,利用下面代碼,通過(guò)逐行讀取的方式將數(shù)據(jù)讀取到內(nèi)存中。
import csv
f='ascii.txt'
with open(f) as csvfile:
data = list(csv.reader(csvfile))
csvfile.close()
按 Shift + Enter 運(yùn)行代碼塊并創(chuàng)建新的代碼塊,在新的代碼塊中輸入變量名可直接查看該變量的值,這里輸入并運(yùn)行。觀察數(shù)據(jù)的組織結(jié)構(gòu)可以發(fā)現(xiàn),該數(shù)據(jù)由兩個(gè)部分組成分別是文件頭和數(shù)據(jù)主體兩個(gè)部分,這兩個(gè)部分需要分開(kāi)處理。
data

文件頭通常由幾行字符串組成。Python 本身對(duì)于字符串有很強(qiáng)大的處理能力,這里展示了兩種文件頭的處理方式:
ls1 = []
ls2 = []
# 使用字符串拆分手段獲取列名
for i in range(2,7):
s = data[i][0]
class_name = s.split(': ')[-1].split('~~')[0]
ls1.append(class_name)
print(ls1)
# 使用正則表達(dá)式匹配方法獲取列名
import re
for i in range(2,7):
s = data[i][0]
class_name = re.search(r'.*: (.*?)~.*', s).group(1)
ls2.append(class_name)
print(ls2)
# 需要注意數(shù)據(jù)中的空格
輸出結(jié)果:
['tree', 'soil', 'water', 'maize', 'road']
['tree', 'soil', 'water', 'maize', 'road']
本文件的數(shù)據(jù)主體部分由固定寬度的幾列數(shù)字組成,對(duì)于這種組織形式可以使用 Pandas.read_fwf() 進(jìn)行解析。
import pandas as pd
colspecs = [(0,13),(13,23),(23,33),(33,43),(43,53),(53,63)]
table = pd.read_fwf('ascii.txt',skiprows=7,header=None,colspecs=colspecs)
#在數(shù)據(jù)存儲(chǔ)中推薦使用以逗號(hào)分隔符進(jìn)行數(shù)據(jù)存儲(chǔ),這樣數(shù)據(jù)更易于解析。例如Python本身就對(duì)逗號(hào)分割的數(shù)據(jù)具有解析功能,而固定寬度的數(shù)據(jù)需要調(diào)用復(fù)雜的函數(shù),提高了數(shù)據(jù)傳遞的難度。
# 調(diào)整數(shù)據(jù)的顯示
table = table.set_index(0)
table.columns = ls1
table.index.name = 'wavelength'
table
輸出結(jié)果:

至此便完成了ENVI波譜庫(kù)的解析工作。使用Python的科學(xué)計(jì)算庫(kù)可以完成所有常規(guī)的高光譜處理工作, 如繪圖,插值,統(tǒng)計(jì),回歸等。
# 繪圖
table.plot()
輸出結(jié)果:

# 四則運(yùn)算與統(tǒng)計(jì)
t_s = table['tree'] - table['soil']
table['tree'] = table['soil'] + t_s
table['tree'] = table['tree']*100
table['tree'] = table['tree']/100
table.describe()
輸出結(jié)果:

# 上下包絡(luò)線計(jì)算 https://stackoverflow.com/questions/34235530/how-to-get-high-and- low-envelope-of-a-signal/34245942#34245942
from matplotlib import pyplot as plt
def hl_envelopes_idx(s, dmin=1, dmax=1, split=False):
"""
Input :
s: 1d-array, data signal from which to extract high and low envelopes dmin, dmax: int, optional, size of chunks, use this if the size of the input signal is too big
split: bool, optional, if True, split the signal in half along its mean, might help to generate the envelope in some cases
Output :
lmin,lmax : high/low envelope idx of input signal s
"""
# locals min
lmin = (np.diff(np.sign(np.diff(s))) > 0).nonzero()[0] + 1
# locals max
lmax = (np.diff(np.sign(np.diff(s))) < 0).nonzero()[0] + 1
if split:
# s_mid is zero if s centered around x-axis or more generally mean of signal
s_mid = np.mean(s)
# pre-sorting of locals min based on relative position with respect to s_mid
lmin = lmin[s[lmin]<s_mid]
# pre-sorting of local max based on relative position with respect to s_mid
lmax = lmax[s[lmax]>s_mid]
# global min of dmin-chunks of locals min
lmin = lmin[[i+np.argmin(s[lmin[i:i+dmin]]) for i in range(0,len(lmin),dmin)]]
# global max of dmax-chunks of locals max
lmax = lmax[[i+np.argmax(s[lmax[i:i+dmax]]) for i in range(0,len(lmax),dmax)]]
return lmin,lmax
y='tree'
l_en,h_en = hl_envelopes_idx(table[y].values) plt.plot(table.iloc[h_en].index,table.iloc[h_en][y],label = 'High Envelope') plt.plot(table.index,table[y],label = 'data',color = 'black') plt.plot(table.iloc[l_en].index,table.iloc[l_en][y],label = 'Low Envelope') plt.legend()
輸出結(jié)果:

小結(jié)
本文介紹了使用Python處理高光譜數(shù)據(jù)的優(yōu)勢(shì),開(kāi)發(fā)環(huán)境的安裝,以及光譜庫(kù)文件的讀取與處理。千里之行,始于足下。高光譜圖像是由網(wǎng)格化的單根光譜曲線組成的,其處理思路與單個(gè)光譜曲線的處理有很多一致性。所以有必要理解如何對(duì)單根光譜曲線進(jìn)行處理,并將這些處理方法應(yīng)用于高光譜影像。此外,高光譜影像作為地理影像,包含單根光譜曲線沒(méi)有的空間信息,其數(shù)據(jù)量也達(dá)到了大數(shù)據(jù)的級(jí)別, 因此高光譜圖像的處理又有其特殊的地方。
相關(guān)產(chǎn)品
全部評(píng)論(0條)
登錄或新用戶注冊(cè)
請(qǐng)用手機(jī)微信掃描下方二維碼
快速登錄或注冊(cè)新賬號(hào)
微信掃碼,手機(jī)電腦聯(lián)動(dòng)
推薦方案
相關(guān)解決方案
參與評(píng)論
登錄后參與評(píng)論