基于Python高光谱遥感影像处理实例

2023-05-16

前言

在写波段配准相关代码时经常需要用到tif影像的波段合成和分解,虽然可以用ENVI才处理,但是每次都要打开再设置一些参数有些麻烦,所以本着“独立自主、自力更生”的原则就写了些脚本来处理这个需求。又写了个批量裁剪影像的脚本。这里简单总结归纳一下。

1.波段合并

# coding=utf-8
import sys
import cv2
import functions as fun
import os

if __name__ == '__main__':
    if sys.argv.__len__() >= 2:
        if sys.argv[1] == 'help' or sys.argv[1] == 'HELP':
            print("Function description:")
            print("Join several bands into one file.")
            print("\nUsage instruction:")
            print("example.exe [img_dir] [img_type] [out_path]")
            print("[img_dir]:The input dir that contains band data.")
            print("[img_type]:The file type of band data,tif or png etc.")
            print("[out_path]:The filename of joined image.")
            print("Please note that these band data should have same height and width.")
            print("\nUsage example:")
            print("Tool_JoinBands.exe C:\\tif tif C:\\tifout\\joined.tif")
            os.system('pause')
        else:
            img_dir = sys.argv[1]
            img_type = sys.argv[2]
            out_path = sys.argv[3]
            paths, names, files = fun.findAllFiles(img_dir, img_type)
            bands_data = []

            # 对于tif文件,统一用gdal打开并输出为tif文件
            if img_type.endswith('tif') or img_type.endswith('TIF') or img_type.endswith('TIFF') or img_type.endswith(
                    'tiff'):
                for i in range(files.__len__()):
                    band_data = fun.readTifImage(files[i])
                    bands_data.extend(band_data)
                    print("joined " + (i + 1).__str__() + " bands.")
                print(bands_data.__len__().__str__() + " bands in total.")
                fun.writeTif(bands_data, out_path)
            # 对于所有其它类型的文件,如jpg、png等,统一用OpenCV处理
            else:
                for i in range(files.__len__()):
                    band_data = cv2.imread(files[i], cv2.IMREAD_GRAYSCALE)
                    bands_data.append(band_data)
                print("Open image success.")
                data = cv2.merge((bands_data[0], bands_data[1], bands_data[2]))
                cv2.imwrite(out_path, data)
                print("Save image success.")
    else:
        print("Unknown mode, input 'yourExeName.exe help' to get help information.")

这里简单介绍下代码。经过波段配准后,不同波段的影像已经实现了对齐,所以通过读取各波段影像然后利用GDAL叠加即可。

2.波段拆分

# coding=utf-8
import sys
import os
import cv2
import functions as fun

if __name__ == '__main__':
    if sys.argv.__len__() >= 2:
        if sys.argv[1] == 'help' or sys.argv[1] == 'HELP':
            print("Function description:")
            print("Separate and save different band data in one image file.")
            print("\nUsage instruction:")
            print("example.exe [img_path] [out_dir]")
            print("[img_path]:The filename of input image.")
            print("[output_dir]:The output dir for different band images.")
            print("\nUsage example:")
            print("Tool_SeparateBands.exe C:\\tif\\input.tif C:\\tifout")
            os.system('pause')

        else:
            img_path = sys.argv[1]
            output_dir = sys.argv[2]

            # 对于tif文件,统一用gdal打开并输出为tif文件
            if img_path.endswith('tif') or img_path.endswith('TIF') or img_path.endswith('TIFF') or img_path.endswith(
                    'tiff'):
                bands_data = fun.readTifImage(img_path)
                for i in range(bands_data.__len__()):
                    fun.writeTif([bands_data[i]], output_dir + os.path.sep + "band_" + i.__str__().zfill(2) + ".tif")
                    print("saved " + (i + 1).__str__() + "/" + bands_data.__len__().__str__())
            # 对于所有其它类型的文件,如jpg、png等,统一用OpenCV处理
            else:
                img = cv2.imread(img_path)
                print("Open image success.")
                band_b, band_g, band_r = cv2.split(img)
                cv2.imwrite(output_dir + os.path.sep + "band_b.png", band_b)
                cv2.imwrite(output_dir + os.path.sep + "band_g.png", band_g)
                cv2.imwrite(output_dir + os.path.sep + "band_r.png", band_r)
                print("Save image success.")

    else:
        print("Unknown mode, input 'yourExeName.exe help' to get help information.")

波段拆分与波段合并相反,直接读取一个多波段的tif影像,然后依次保存各波段数据为单独文件即可。

3.影像裁剪

在之前,要想实现影像裁剪的功能需要借助ENVI等软件,但是ENVI等打开比较慢,还要各种设置,比较麻烦。所以直接写了个脚本来方便地实现功能

# coding=utf-8
import sys
import cv2
import functions as fun
import os

if __name__ == '__main__':
    if sys.argv.__len__() >= 2:
        if sys.argv[1] == 'help' or sys.argv[1] == 'HELP':
            print("Function description:")
            print("Select and cut the ROI(region of interest) in a big image file.")
            print("\nUsage instruction:")
            print("example.exe [img_path] [out_path] [start_x] [start_y] [x_range] [y_range]")
            print("[img_path]:The filename of input image.")
            print("[out_path]:The filename of output image.")
            print("[start_x]:The x coordinate of ROI's left-top point in big image.")
            print("[start_y]:The y coordinate of ROI's left-top point in big image.")
            print("[x_range]:The range of ROI in x direction(width).")
            print("[y_range]:The range of ROI in y direction(height).")
            print("\nUsage example:")
            print("Tool_ResizeIMG.exe C:\\tif\\input.tif C:\\tifout\\roi.tif 100 200 3000 4000")
            os.system('pause')
        else:
            img_path = sys.argv[1]
            out_path = sys.argv[2]
            start_x = int(sys.argv[3])
            start_y = int(sys.argv[4])
            x_range = int(sys.argv[5])
            y_range = int(sys.argv[6])
            # 对于tif文件,统一用gdal打开并输出为tif文件
            if img_path.endswith('tif') or img_path.endswith('TIF') or img_path.endswith('TIFF') or img_path.endswith(
                    'tiff'):
                bands_data = fun.readTifImageWithWindow(img_path, start_x, start_y, x_range, y_range)
                fun.writeTif(bands_data, out_path)
            # 对于所有其它类型的文件,如jpg、png等,统一用OpenCV处理
            else:
                bands_data = cv2.imread(img_path)
                print("Open image success.")
                bands_data_roi = bands_data[start_y:start_y + y_range, start_x:start_x + x_range, :]
                cv2.imwrite(out_path, bands_data_roi)
                print("Save image success.")
    else:
        print("Unknown mode, input 'yourExeName.exe help' to get help information.")

影像裁剪实现也相对简单,就是通过设置读取影像范围即可实现对指定区域的裁剪。

4.批量影像裁剪

# coding=utf-8
import sys
import cv2
import functions as fun
import os

if __name__ == '__main__':
    if sys.argv.__len__() >= 2:
        if sys.argv[1] == 'help' or sys.argv[1] == 'HELP':
            print("Function description:")
            print("Select and cut the ROI(region of interest) in big image files(Batch mode).")
            print("\nUsage instruction:")
            print("example.exe [img_dir] [img_type] [output_dir] [start_x] [start_y] [x_range] [y_range]")
            print("[img_dir]:The input dir that contains band data.")
            print("[img_type]:The file type of band data,tif or png etc.")
            print("[output_dir]:The output dir for ROI images.")
            print("[start_x]:The x coordinate of ROI's left-top point in big image.")
            print("[start_y]:The y coordinate of ROI's left-top point in big image.")
            print("[x_range]:The range of ROI in x direction(width).")
            print("[y_range]:The range of ROI in y direction(height).")
            print("\nUsage example:")
            print("Tool_ResizeIMG_Batch.exe C:\\tif tif C:\\tifout 100 200 3000 4000")
            os.system('pause')
        else:
            img_dir = sys.argv[1]
            img_type = sys.argv[2]
            out_dir = sys.argv[3]
            start_x = int(sys.argv[4])
            start_y = int(sys.argv[5])
            x_range = int(sys.argv[6])
            y_range = int(sys.argv[7])

            paths, names, files = fun.findAllFiles(img_dir, img_type)
            # 对于tif文件,统一用gdal打开并输出为tif文件
            if img_type.endswith('tif') or img_type.endswith('TIF') or img_type.endswith('TIFF') or img_type.endswith(
                    'tiff'):
                for i in range(files.__len__()):
                    bands_data = fun.readTifImageWithWindow(files[i], start_x, start_y, x_range, y_range)
                    fun.writeTif(bands_data, out_dir + os.path.sep + names[i][:names[i].rfind('.')] + "_cut.tif")
                    print("cutting " + (i + 1).__str__() + "/" + files.__len__().__str__())
                print('cut finished.')
            # 对于所有其它类型的文件,如jpg、png等,统一用OpenCV处理
            else:
                for i in range(files.__len__()):
                    bands_data = cv2.imread(files[i])
                    bands_data_roi = bands_data[start_y:start_y + y_range, start_x:start_x + x_range, :]
                    cv2.imwrite(out_dir + os.path.sep + "band_" + (i + 1).__str__().zfill(2) + ".jpg", bands_data_roi)
                    print("cutting " + (i + 1).__str__() + "/" + files.__len__())
                print('cut finished.')
    else:
        print("Unknown mode, input 'yourExeName.exe help' to get help information.")

相比于单张影像裁剪,批量裁剪就是多加了个循环,实现了批量操作,也比较简单。

5.模块functions如下:

functions.py

# coding=utf-8
import os
import cv2
import numpy as np
from osgeo import gdal
from gdalconst import *


def readTifImage(img_path):
    data = []
    # 以只读方式打开遥感影像
    dataset = gdal.Open(img_path, GA_ReadOnly)
    if dataset is None:
        print("Unable to open image file.")
        return data
    else:
        print("Open image file success.")
        bands_num = dataset.RasterCount
        print("Image height:" + dataset.RasterYSize.__str__() + " Image width:" + dataset.RasterXSize.__str__())
        print(bands_num.__str__() + " bands in total.")
        for i in range(bands_num):
            # 获取影像的第i+1个波段
            band_i = dataset.GetRasterBand(i + 1)
            # 读取第i+1个波段数据
            band_data = band_i.ReadAsArray(0, 0, band_i.XSize, band_i.YSize)
            data.append(band_data)
            print("band " + (i + 1).__str__() + " read success.")
        return data

def writeTif(bands, path):
    if bands is None or bands.__len__() == 0:
        return
    else:
        # 认为各波段大小相等,所以以第一波段信息作为保存
        band1 = bands[0]
        # 设置影像保存大小、波段数
        img_width = band1.shape[1]
        img_height = band1.shape[0]
        num_bands = bands.__len__()

        # 设置保存影像的数据类型
        if 'int8' in band1.dtype.name:
            datatype = gdal.GDT_Byte
        elif 'int16' in band1.dtype.name:
            datatype = gdal.GDT_UInt16
        else:
            datatype = gdal.GDT_Float32

        # 创建文件
        driver = gdal.GetDriverByName("GTiff")
        dataset = driver.Create(path, img_width, img_height, num_bands, datatype)
        if dataset is not None:
            for i in range(bands.__len__()):
                dataset.GetRasterBand(i + 1).WriteArray(bands[i])
        print("save image success.")

def readTifImageWithWindow(img_path, start_x, start_y, x_range, y_range):
    data = []
    # 以只读方式打开遥感影像
    dataset = gdal.Open(img_path, GA_ReadOnly)
    if dataset is None:
        print("Unable to open image file.")
        return data
    else:
        print("Open image file success.")
        bands_num = dataset.RasterCount
        print("Image height:" + dataset.RasterYSize.__str__() + " Image width:" + dataset.RasterXSize.__str__())
        print(bands_num.__str__() + " bands in total.")
        for i in range(bands_num):
            # 获取影像的第i+1个波段
            band_i = dataset.GetRasterBand(i + 1)
            # 读取第i+1个波段数据
            band_data = band_i.ReadAsArray(start_x, start_y, x_range, y_range)
            data.append(band_data)
            print("band " + (i + 1).__str__() + " read success.")
        return data

def findAllFiles(root_dir, filter):
    print("Finding files ends with \'" + filter + "\' ...")
    separator = os.path.sep
    paths = []
    names = []
    files = []
    # 遍历
    for parent, dirname, filenames in os.walk(root_dir):
        for filename in filenames:
            if filename.endswith(filter):
                paths.append(parent + separator)
                names.append(filename)
    for i in range(paths.__len__()):
        files.append(paths[i] + names[i])
    print (names.__len__().__str__() + " files have been found.")
    paths.sort()
    names.sort()
    files.sort()
    return paths, names, 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于Python高光谱遥感影像处理实例 的相关文章

  • 如何查看Databricks中的所有数据库和表

    我想列出 Azure Databricks 中每个数据库中的所有表 所以我希望输出看起来像这样 Database Table name Database1 Table 1 Database1 Table 2 Database1 Table
  • 通过 Scrapy 抓取 Google Analytics

    我一直在尝试使用 Scrapy 从 Google Analytics 获取一些数据 尽管我是一个完全的 Python 新手 但我已经取得了一些进展 我现在可以通过 Scrapy 登录 Google Analytics 但我需要发出 AJAX
  • 将数据从 python pandas 数据框导出或写入 MS Access 表

    我正在尝试将数据从 python pandas 数据框导出到现有的 MS Access 表 我想用已更新的数据替换 MS Access 表 在 python 中 我尝试使用 pandas to sql 但收到错误消息 我觉得很奇怪 使用 p
  • 使用带有关键字参数的 map() 函数

    这是我尝试使用的循环map功能于 volume ids 1 2 3 4 5 ip 172 12 13 122 for volume id in volume ids my function volume id ip ip 我有办法做到这一点
  • Django:按钮链接

    我是一名 Django 新手用户 尝试创建一个按钮 单击该按钮会链接到我网站中的另一个页面 我尝试了一些不同的例子 但似乎没有一个对我有用 举个例子 为什么这不起作用
  • 使用 on_bad_lines 将 pandas.read_csv 中的无效行写入文件

    我有一个 CSV 文件 我正在使用 Python 来解析该文件 我发现文件中的某些行具有不同的列数 001 Snow Jon 19801201 002 Crom Jake 19920103 003 Wise Frank 19880303 l
  • 如何替换 pandas 数据框列中的重音符号

    我有一个数据框dataSwiss其中包含瑞士城市的信息 我想用普通字母替换带有重音符号的字母 这就是我正在做的 dataSwiss Municipality dataSwiss Municipality str encode utf 8 d
  • Python pickle:腌制对象不等于源对象

    我认为这是预期的行为 但想检查一下 也许找出原因 因为我所做的研究结果是空白 我有一个函数可以提取数据 创建自定义类的新实例 然后将其附加到列表中 该类仅包含变量 然后 我使用协议 2 作为二进制文件将该列表腌制到文件中 稍后我重新运行脚本
  • 从 Flask 访问 Heroku 变量

    我已经使用以下命令在 Heroku 配置中设置了数据库变量 heroku config add server xxx xxx xxx xxx heroku config add user userName heroku config add
  • Flask如何获取请求的HTTP_ORIGIN

    我想用我自己设置的 Access Control Allow Origin 标头做出响应 而弄清楚请求中的 HTTP ORIGIN 参数在哪里似乎很混乱 我在用着烧瓶 0 10 1 以及HTTP ORIGIN似乎是这个的特点之一object
  • Python 的“zip”内置函数的 Ruby 等价物是什么?

    Ruby 是否有与 Python 内置函数等效的东西zip功能 如果不是 做同样事情的简洁方法是什么 一些背景信息 当我试图找到一种干净的方法来进行涉及两个数组的检查时 出现了这个问题 如果我有zip 我可以写这样的东西 zip a b a
  • 在Python中获取文件描述符的位置

    比如说 我有一个原始数字文件描述符 我需要根据它获取文件中的当前位置 import os psutil some code that works with file lp lib open path to file p psutil Pro
  • 在f字符串中转义字符[重复]

    这个问题在这里已经有答案了 我遇到了以下问题f string gt gt gt a hello how to print hello gt gt gt f a a gt gt gt f a File
  • python获取上传/下载速度

    我想在我的计算机上监控上传和下载速度 一个名为 conky 的程序已经在 conky conf 中执行了以下操作 Connection quality alignr wireless link qual perc wlan0 downspe
  • 将图像分割成多个网格

    我使用下面的代码将图像分割成网格的 20 个相等的部分 import cv2 im cv2 imread apple jpg im cv2 resize im 1000 500 imgwidth im shape 0 imgheight i
  • 使用其构造函数初始化 OrderedDict 以便保留初始数据的顺序的正确方法?

    初始化有序字典 OD 以使其保留初始数据的顺序的正确方法是什么 from collections import OrderedDict Obviously wrong because regular dict loses order d O
  • 在 Qt 中自动调整标签文本大小 - 奇怪的行为

    在 Qt 中 我有一个复合小部件 它由排列在 QBoxLayouts 内的多个 QLabels 组成 当小部件调整大小时 我希望标签文本缩放以填充标签区域 并且我已经在 resizeEvent 中实现了文本大小的调整 这可行 但似乎发生了某
  • Rocket UniData/UniVerse:ODBC 无法分配足够的内存

    每当我尝试使用pyodbc连接到 Rocket UniData UniVerse 数据时我不断遇到错误 pyodbc Error 00000 00000 Rocket U2 U2ODBC 0302810 Unable to allocate
  • Python Selenium:如何在文本文件中打印网站上的值?

    我正在尝试编写一个脚本 该脚本将从 tulsaspca org 网站获取以下 6 个值并将其打印在 txt 文件中 最终输出应该是 905 4896 7105 23194 1004 42000 放置的动物 的 HTML span class
  • 如何使用 Pycharm 安装 tkinter? [复制]

    这个问题在这里已经有答案了 I used sudo apt get install python3 6 tk而且效果很好 如果我在终端中打开 python Tkinter 就可以工作 但我无法将其安装在我的 Pycharm 项目上 pip

随机推荐

  • python3.6-深入浅出视频

    课程收益 适合人群 python小白 xff0c 大数据和机器学习编程程序员 上机实践为主线 以最快的速度上手 快速入门 xff0c 还学到了python3的核心知识 https edu csdn net course detail 989
  • 数学之路(3)-机器学习(3)-机器学习算法-神经网络[11]

    多层感知器的代码 xff0c 需要一个比较复杂的调试过程 xff0c 不过也有一些方法来加快这一速度 xff0c 其中有几个地方要注意 xff1a 1 输入层 输出层 中间层的学习率和动量参数不能一样 xff0c 2 3个层的权值策略不能一
  • 14、iOS里面的富文本

    iOS里面的富文本 1 NSAttributedString属性概览表2 属性详解及应用2 1 NSAttributedString Key font 字体大小2 2 NSAttributedString Key paragraphStyl
  • 马化腾五兄弟:难得的创业团队

    http www donews com people 201105 455471 shtm 腾讯的马化腾创业5兄弟 xff0c 堪称难得 xff0c 其理性堪称标本 12年前的那个秋天 xff0c 马化腾与他的同学张志东 合资 注册了深圳腾
  • 选择创业团队的类型

    从不同的角度 层次和结构 xff0c 可以划分为不同类型的创业团队 xff0c 而依据创业团队的组成者来划分 xff0c 创业团队有星状创业团队 xff08 Star Team xff09 网状创业团队 xff08 Net Team xff
  • MQTT3.1与UDP时效性分析

    前言 MQTT 3 1协议在弱网络环境下 xff08 比如2G 3G等 xff09 表现不够好 xff0c 因此才有了反思 弱网环境下表现 手机等终端在弱网络环境下丢包情况会非常明显 xff0c 连接MQTT Server成功率很低 相比单
  • Android APP开机自启动基本方法

    前言 应用自启动主要是通过接收系统广播BOOT COMPLETED来实现的 xff0c 在receiver中执行APP启动的方法 实现 主要分为两个部分 xff1a AndroidManifest xml配置 xff0c 包括权限配置和广播
  • gitlab markdown 支持TOC解决办法

    问题分析 1 标题的锚点会被替换 中文替换为 39 39 空格等非正常字符替换为 39 39 这给自己手动写toc也带来了麻烦 不能直接复制标题作为链接 2 不能自动生成TOC 目前gitlab不支持TOC功能 解决方法 1 解决中文问题
  • 数据科学家能力发展路线图

  • 每秒处理10万订单乐视集团支付架构

    随着乐视硬件抢购的不断升级 xff0c 乐视集团支付面临的请求压力百倍乃至千倍的暴增 作为商品购买的最后一环 xff0c 保证用户快速稳定的完成支付尤为重要 所以在15年11月 xff0c 我们对整个支付系统进行了全面的架构升级 xff0c
  • 一次心惊肉跳的服务器误删文件的恢复过程

    经历了两天不懈努力 xff0c 终于恢复了一次误操作删除的生产服务器数据 对本次事故过程和解决办法记录在此 xff0c 警醒自己 xff0c 也提示别人莫犯此错 也希望遇到问题的朋友能找到一丝灵感解决问题 事故背景 安排一个妹子在一台生产服
  • WIFI模块的各种配网方式之比较(串口AT、SmartConfig、微信Airkiss、WEB网页配网....)

    WIFI模块的各种配网方式之比较 如何对WIFI模块进行配网 xff1f 串口AT xff1f 微信Airkiss xff1f SmartConfig xff1f No xff01 WEB网页配网最简单 最方便 所受限制也最少 xff01
  • Android studio2.3.2 配置kotlin、Anko

    祝 xff1a 本文配置基于Android studio 2 3 2 xff0c gradle3 3 jdk1 8 1 下载kotlin插件 打开Settings面板 xff0c 找到Plugins选项 xff0c 点击Browse rep
  • TCP/UDP的套接字Socket通信工作流程

    一 面向连接的套接字Socket通信工作流程 为了实现服务器与客户机的通信 服务器和客户机都必须建立套接字 服务器与客户机的工作原理可以用下面的过程来描述 1 服务器先用 socket 函数来建立一个套接字 用这个套接字完成通信的监听 2
  • VirtualBox 如何能捕获/释放鼠标

    xff11 xff0e 热键的选项 xff1a 鼠标集成不选择 xff12 xff0e 当你点击虚拟机的时候会出现下图 xff0c 选择捕获就可以了 xff13 xff0e 但你无法移出到外面主机的时候 xff0c 按住键盘右侧的Ctrl移
  • onNewIntent触发的时机

    前提 ActivityA已经启动过 处于当前应用的Activity堆栈中 当ActivityA的LaunchMode为SingleTop时 xff0c 如果ActivityA在栈顶 且现在要再启动ActivityA xff0c 这时会调用o
  • tomcat各版本下载地址

    https archive apache org dist tomcat
  • Android屏幕尺寸适配常见方案smallestWidth

    前言 介于目前的Android设备存在有不同的屏幕尺寸 xff0c 屏幕分辨率 xff0c 像素密度 xff0c Android应用在开发的过程必须要考虑到屏幕尺寸适配的问题 xff0c 以保证在不同尺寸的Android设备上都能够正常运行
  • 奇数阶魔方阵!

    import java util Scanner public class Test5 打印 魔方阵 所谓的魔方阵是指这样的方阵 xff0c 它的行 列 对角线元素之和均相等 以下是奇数阶魔方阵 xff01 xff01 xff01 xff0
  • 基于Python高光谱遥感影像处理实例

    前言 在写波段配准相关代码时经常需要用到tif影像的波段合成和分解 xff0c 虽然可以用ENVI才处理 xff0c 但是每次都要打开再设置一些参数有些麻烦 xff0c 所以本着 独立自主 自力更生 的原则就写了些脚本来处理这个需求 又写了