python实现遥感图像包络线去除

包络线去除是光谱识别中一个重要的步骤,算法如下:
    (1)通过求导得到光谱曲线上所有极大值点,即“峰”值点,然后比较大小,得到极大值点中的最大值点;
    (2)以最大值点作为包络线的一个端点,计算该点与长波方向(波长增长的方向)各个极大值连线的斜率,以斜率最大点作为包络线下一个端点,再以此点为起点循环,直至最后一点;
    (3)以最大值点作为包选线的一个端点,向短波(波长减少的方向)进行类似计算,以斜率最小点为下个端点,再以此点为起点循环,直至曲线上的开始点;
    (4)沿长波方向连接所有端点,可形成曲线的包络线,用实际光谱反射率去除包络线上相应波段的反射率值,可得到包络线消除法归一化后的值。
--------------------- 
版权声明:本文为CSDN博主「small山炮」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jikechong/article/details/80557366

结果:红:原始数据,绿:包络线,蓝:归一化值

python实现遥感图像包络线去除_第1张图片

输入数据:                                                                               输出结果:

python实现遥感图像包络线去除_第2张图片                              python实现遥感图像包络线去除_第3张图片

输入数据主要有九列,第一列为波长,每列为一个波段数据;输出为每列归一化值

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列),任何问题请留言

你可能感兴趣的:(python)