包络线去除是光谱识别中一个重要的步骤,算法如下:
(1)通过求导得到光谱曲线上所有极大值点,即“峰”值点,然后比较大小,得到极大值点中的最大值点;
(2)以最大值点作为包络线的一个端点,计算该点与长波方向(波长增长的方向)各个极大值连线的斜率,以斜率最大点作为包络线下一个端点,再以此点为起点循环,直至最后一点;
(3)以最大值点作为包选线的一个端点,向短波(波长减少的方向)进行类似计算,以斜率最小点为下个端点,再以此点为起点循环,直至曲线上的开始点;
(4)沿长波方向连接所有端点,可形成曲线的包络线,用实际光谱反射率去除包络线上相应波段的反射率值,可得到包络线消除法归一化后的值。
---------------------
版权声明:本文为CSDN博主「small山炮」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jikechong/article/details/80557366
结果:红:原始数据,绿:包络线,蓝:归一化值
输入数据: 输出结果:
输入数据主要有九列,第一列为波长,每列为一个波段数据;输出为每列归一化值
main()中的三个参数分别指定输入文件,输出文件路径及名称,被展示的一列。
代码在第40行将判断极大值修改为:
y[index] - y[index - 1] > y[index + 1] - y[index]
如果希望找最大值可以用:
y[index] > y[index - 1] and y[index] > y[index + 1]
import matplotlib.pyplot as plt
import numpy as np
def getData(fileName):
feedlist = open(fileName)
x = []
y = []
i = 0
for i in range(0, 9):
y.append([])
i = 0
for feedurl in feedlist:
if (i > 10):
feedurl = feedurl.strip('\n')
feedur2 = feedurl.strip().split(" ")
x.append(float(feedur2[0]))
for j in range(0, 9):
y[j].append(float(feedur2[j + 1]))
else:
i += 1
return x, y
def drawOrign(x, y, y1, y2):
plt.plot(x, y, color='r')
plt.plot(x, y1, color='g')
plt.plot(x, y2, color='b')
plt.xlim(0)
plt.ylim(0)
plt.show()
def getMax(x, y):
maxXs = []
maxYs = []
maxXs.append(x[0])
maxYs.append(y[0])
for index in range(1, x.__len__() - 1):
if (y[index] - y[index - 1] > y[index + 1] - y[index]):
maxXs.append(x[index])
maxYs.append(y[index])
maxXs.append(x[x.__len__() - 1])
maxYs.append(y[y.__len__() - 1])
return maxXs, maxYs
def getStart(maxXs, maxYs):
maxIndex = np.argmax(maxYs)
startPointX = maxXs[maxIndex]
startPointY = maxYs[maxIndex]
return maxIndex, startPointX, startPointY
def getNextR(maxYs, maxXs, maxIndex, startPointX, startPointY):
xNextR = []
yNextR = []
pointIndex = maxIndex
indexPointX = startPointX
indexPointY = startPointY
while (pointIndex < maxXs.__len__() - 1):
kMax = -999999
for index in range(pointIndex + 1, maxXs.__len__()):
k = (maxYs[index] - indexPointY) / (maxXs[index] - indexPointX)
if (kMax < k):
kMax = k
nextIndex = index
pointIndex = nextIndex
indexPointX = maxXs[pointIndex]
indexPointY = maxYs[pointIndex]
xNextR.append(indexPointX)
yNextR.append(indexPointY)
if (xNextR[xNextR.__len__() - 1] != maxXs[maxXs.__len__() - 1]):
xNextR.append(maxXs[maxXs.__len__() - 1])
yNextR.append(maxYs[maxYs.__len__() - 1])
return xNextR, yNextR
def getNextL(maxYs, maxXs, maxIndex, startPointX, startPointY):
xNextL = []
yNextL = []
pointIndex = maxIndex
indexPointX = startPointX
indexPointY = startPointY
while (pointIndex > 1):
kMin = 999999
for index in range(pointIndex - 1, 0, -1):
k = (maxYs[index] - indexPointY) / (maxXs[index] - indexPointX)
if (kMin > k):
kMin = k
nextIndex = index
pointIndex = nextIndex
indexPointX = maxXs[pointIndex]
indexPointY = maxYs[pointIndex]
xNextL.append(indexPointX)
yNextL.append(indexPointY)
if (xNextL[xNextL.__len__() - 1] != maxXs[0]):
xNextL.append(maxXs[0])
yNextL.append(maxYs[0])
return xNextL, yNextL
def doExtend(xNextL, yNextL, xNextR, yNextR, startPointX, startPointY):
xNextL.reverse()
yNextL.reverse()
xNextL += [startPointX]
xNextL += xNextR
yNextL += [startPointY]
yNextL += yNextR
return xNextL, yNextL
def doInsert(xNext, yNext):
yInsert = []
for i in range(xNext.__len__() - 1):
x = xNext[i]
y = yNext[i]
yInsert.append(y)
k = (yNext[i + 1] - yNext[i]) / (xNext[i + 1] - xNext[i])
b = yNext[i] - xNext[i] * k
while x < xNext[i + 1] - 1:
x += 1
y = k * x + b
yInsert.append(y)
yInsert.append(yNext[yNext.__len__() - 1])
return yInsert
def getResult(x, y, yInsert):
yResult = []
for i in range(x.__len__()):
yResult.append(y[i] / yInsert[i])
return yResult
def writeResult(flieNmae, x, yResult):
fp = open(flieNmae, 'w')
for i in range(x.__len__()):
fp.write("%.6f " % x[i])
for j in range(9):
fp.write("%.6f " % yResult[j][i])
fp.write('\n')
def startDeal(fileName, column, resultName):
x, y = getData(fileName)
yResult = []
for i in range(0, 9):
maxXs, maxYs = getMax(x, y[i])
maxIndex, startPointX, startPointY = getStart(maxXs, maxYs)
xNextR, yNextR = getNextR(maxYs, maxXs, maxIndex, startPointX, startPointY)
xNextL, yNextL = getNextL(maxYs, maxXs, maxIndex, startPointX, startPointY)
xNext, yNext = doExtend(xNextL, yNextL, xNextR, yNextR, startPointX, startPointY)
yInsert = doInsert(xNext, yNext)
yResult.append(getResult(x, y[i], yInsert))
if (i == column):
drawOrign(x, y[i], yInsert, yResult[i])
writeResult(resultName, x, yResult)
def main():
# 输入文件路径及名称
fileName = 'test1.txt' # 相对路径或者绝对路径,本处为相对路径,删除了文件头
# 修改展示列
column = 1
# 输出文件路径及名称
resultName = 'result1.txt' # 格式输入文件
startDeal(fileName, column, resultName)
if __name__ == '__main__':
main()
代码很简单就不介绍了,可能需要根据自己的输入文件修改getData函数及一些9(本文件9列),任何问题请留言