(二)BSQ,BIL,BIP存储格式的相互转换算法

news/2024/7/21 5:26:37 标签: java, 图像处理, GDAL, GIS, 算法

环境:Windows10专业版 + IDEA2021.2.3 + jdk11.0.1 + GDAL(release-1928-x64-gdal-3-5-2-mapserver-8-0-0)

系列文章:

(一)Python+GDAL实现BSQ,BIP,BIL格式的相互转换

(二)BSQ,BIL,BIP存储格式的相互转换算法

(三)单波段图像的伪彩色合成:密度分割(含介绍OpenCV中的Mat类)

(四)图像的%2线性拉伸

(五)图像的标准假彩色合成

(六)图像的直方图均衡化

(七)图像的均值滤波

(八)图像的中值滤波

(九)图像的高斯低通滤波

(十)图像的梯度倒数加权平滑

(十一)图像的罗伯特梯度锐化

(十二)图像的Sobel梯度锐化

(十三)图像的拉普拉斯梯度锐化


目录

一、BSQ,BIP,BIL格式简介

(1)BSQ (band sequential)

(2)BIL(band interleaved by line format)

(3)BIP(band interleaved by pixel format)

二、代码实现

三、实验结果

图像的元数据

①读取为BSQ格式的存储格式

②BSQ转BIL

③BSQ转BIP 


一、BSQ,BIP,BIL格式简介

(插图来源于@CSDN溯水xiangling)

(1)BSQ (band sequential)

像素按波段顺序存储,先保存第一个波段,保存完毕后再保存第二个波段,以此类推。

优点:①便于进行波段间的运算;②便于进行波段间的运算;

(2)BIL(band interleaved by line format)

像素按行存储,先保存第一个波段的第一行,再保存第二个波段的第一行,以此类推。

优点:①像素的空间位置在列的方向上是连续的,既可以形象地表达空间分布特征,又可以反映像素的光谱特征 ;②具有较快的读取速度

(3)BIP(band interleaved by pixel format)

按像元顺序存储,先保存第一个波段的第一个像元,再保存第二个波段的第一个像元,以此类推。

优点:①便于进行像元间的运算;②可以清晰地反映像元的光谱特征;


这三种格式各有优缺点,通常根据具体的应用场景和处理需求来选择合适的格式。例如,BSQ格式适合在读取特定波段时提高效率,因为同一波段的数据连续存储,而BIP和BIL则在需要同时访问多个波段的像素时更为高效。

在实际的数字图像处理中,可能需要将一种格式转换为另一种格式以便于分析或与其他软件兼容。转换这些格式可以通过编程语言结合GDAL库进行转换,或者使用MATLAB编写脚本来实现批量转换。也可以通过数据处理和格式转换的软件或工具。每种格式都有其特定的存储结构和应用场景,在进行格式转换时需要考虑数据的完整性和准确性。由于数据格式的转换可能涉及到大量的数据处理和计算,因此在进行转换时还需要考虑计算机的性能和存储空间等因素。

二、代码实现

java">import org.gdal.gdal.Band;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconstConstants;

/**
 * @Author: jue_chen
 * @Date: 2022/10/16/ 19:56
 * @Attention: 转载, 引用请注明出处
 */

public class CalculateBands {

    int iXSize;     //图像的列数
    int iYSize;     //图像的行数
    int bandsNum;   //图像的波段数
    int[][][] bandArr;      //存储图像的所有灰度值,BSQ格式

    //获取一副图像的波段信息
    public void getBands(String srcPath) {
        gdal.AllRegister();     //支持所有驱动
        //以只读方式读取数据存入Dataset类型里
        Dataset dataset = gdal.Open(srcPath, gdalconstConstants.GA_ReadOnly);   
        //判断文件是否读取成功
        if (dataset == null) {
            System.out.println("文件读取失败");
            System.out.println(gdal.GetLastErrorMsg());
            System.exit(1);
        }
        iXSize = dataset.getRasterXSize();      //获取图像列数
        iYSize = dataset.getRasterYSize();      //获取图像行数
        bandsNum = dataset.GetRasterCount();   //获取图像波段数

        //定义波段类型的数组存放每一波段的信息
        Band[] band = new Band[bandsNum];
        for (int i = 0; i < bandsNum; i++) {
            band[i] = dataset.GetRasterBand(i + 1); //图像波段的索引值从1开始,不是0
        }

        //三维数组存放具体波段的灰度值,第一维存放波段数,第二维存放波段的行数,第三维存放波段的列数,以BSQ格式存储
        bandArr = new int[bandsNum][iYSize][iXSize];
        for (int i = 0; i < bandsNum; i++) {
            System.out.println("第" + (i + 1) + "波段");
            for (int j = 0; j < bandArr[0].length; j++) {
                band[i].ReadRaster(0, j, iXSize, 1, bandArr[i][j]);     //一次读取一行灰度值数据
                //读取结果输出测试
                for (int k = 0; k < bandArr[0][0].length; k++) {
                    System.out.print(bandArr[i][j][k] + "\t");
                }
                System.out.println();
            }
            System.out.println();
        }
        System.out.println();
    }

    //打印图像所有波段的灰度值
    public void printBandArr(int[][][] bandArr) {
        for (int i = 0; i < bandArr.length; i++) {
            for (int j = 0; j < bandArr[0].length; j++) {
                for (int k = 0; k < bandArr[0][0].length; k++) {
                    System.out.print(bandArr[i][j][k] + "\t");
                }
                System.out.println();
            }
            System.out.println();
        }
    }

    //获得BSQ格式的数组
    public int[][][] getBSQ() {
        return bandArr;
    }

    //BSQ转BIL
    public int[][][] BSQtoBIL(int[][][] bandArrBSQ) {
        //第一维存放波段的行数,第二维存放波段数,第三维存放波段的列数
        int[][][] bandArrBIL = new int[bandArrBSQ[0].length][bandArrBSQ.length][bandArrBSQ[0][0].length];
        for (int i = 0; i < bandArrBSQ[0].length; i++) {   //BSQ的第二维大小
            for (int j = 0; j < bandArrBSQ.length; j++) {  //BSQ的第一维大小
                for (int k = 0; k < bandArrBSQ[0][0].length; k++) { //BSQ的第三维大小
                    bandArrBIL[i][j][k] = bandArrBSQ[j][i][k];
                }
            }
        }
        return bandArrBIL;
    }

    //BSQ转BIP
    public int[][][] BSQtoBIP(int[][][] bandArrBSQ) {
        //第一维存放波段的行数,第二维存放波段的列数,第三维存放波段数
        int[][][] bansArrBIP = new int[bandArrBSQ[0].length][bandArrBSQ[0][0].length][bandArrBSQ.length];
        for (int i = 0; i < bandArrBSQ[0].length; i++) {   //BSQ第二维大小
            for (int j = 0; j < bandArrBSQ[0][0].length; j++) { //BSQ第三维大小
                for (int k = 0; k < bandArrBSQ.length; k++) {   //BSQ第一维大小
                    bansArrBIP[i][j][k] = bandArrBSQ[k][i][j];
                }
            }
        }
        return bansArrBIP;
    }

    //BIL转BSQ
    public int[][][] BILtoBSQ(int[][][] bandArrBIL) {
        //第一维存放波段数,第二维存放波段行数,第三维存放波段列数
        int[][][] bandArrBSQ = new int[bandArrBIL[0].length][bandArrBIL.length][bandArrBIL[0][0].length];
        for (int i = 0; i < bandArrBIL[0].length; i++) {    //BIL第二维大小
            for (int j = 0; j < bandArrBIL.length; j++) {   //BIL第一维大小
                for (int k = 0; k < bandArrBIL[0][0].length; k++) { //BIL第三维大小
                    bandArrBSQ[i][j][k] = bandArrBIL[j][i][k];
                }
            }
        }
        return bandArrBSQ;
    }

    //BIL转BIP
    public int[][][] BILtoBIP(int[][][] bandArrBIL) {
        //第一维存放波段的行数,第二维存放波段的列数,第三维存放波段数
        int[][][] bandArrBIP = new int[bandArrBIL.length][bandArrBIL[0][0].length][bandArrBIL[0].length];
        for (int i = 0; i < bandArrBIL.length; i++) {   //BIL第一维大小
            for (int j = 0; j < bandArrBIL[0][0].length; j++) {   //BIL第三维大小
                for (int k = 0; k < bandArrBIL[0].length; k++) {  //BIL第二维大小
                    bandArrBIP[i][j][k] = bandArrBIL[i][k][j];
                }
            }
        }
        return bandArrBIP;
    }

    //BIP转BSQ
    public int[][][] BIPtoBSQ(int[][][] bandArrBIP) {
        //第一维存放波段数,第二维存放波段行数,第三维存放波段列数
        int[][][] bandArrBSQ = new int[bandArrBIP[0][0].length][bandArrBIP.length][bandArrBIP[0].length];
        for (int i = 0; i < bandArrBIP[0][0].length; i++) { //BIP第三维大小
            for (int j = 0; j < bandArrBIP.length; j++) {   //BIP第一维大小
                for (int k = 0; k < bandArrBIP[0].length; k++) { //BIP第二维大小
                    bandArrBSQ[i][j][k] = bandArrBIP[j][k][i];
                }
            }
        }
        return bandArrBSQ;
    }

    //BIP转BIL
    public int[][][] BIPtoBIL(int[][][] bandArrBIP) {
        //第一维存放波段的行数,第二维存放波段数,第三维存放波段的列数
        int[][][] bandArrBIL = new int[bandArrBIP.length][bandArrBIP[0][0].length][bandArrBIP[0].length];
        for (int i = 0; i < bandArrBIP.length; i++) {   //BIP第一维大小
            for (int j = 0; j < bandArrBIP[0][0].length; j++) {  //BIP第三维大小
                for (int k = 0; k < bandArrBIP[0].length; k++) { //BIP第二维大小
                    bandArrBIL[i][j][k] = bandArrBIP[i][k][j];
                }
            }
        }
        return bandArrBIL;
    }

    public static void main(String[] args) throws Exception {
        CalculateBands img = new CalculateBands();
        img.getBands("D:\\Project\\IDEA_Project\\RS01\\src\\rs01\\img\\9.png"); //读入图像
        int img_rows = img.iYSize;  //图像灰度值的行数
        int img_cols = img.iXSize;  //图像灰度值的列数
        int img_bandNum = img.bandsNum; //图像的波段数
        System.out.println("读入图像每一波段的灰度值行数为:" + img_rows);
        System.out.println("读入图像每一波段的灰度值列数为:" + img_cols);
        System.out.println("读入图像的波段数为:" + img_bandNum);
        System.out.println();
        int[][][] img_bandArrBSQ = img.getBSQ();    //获取以BSQ格式的存储的数组

        //BSQ转为BIL
        int[][][] img_bandArrBIL = img.BSQtoBIL(img_bandArrBSQ);
        System.out.println("BIL的存储格式");
        img.printBandArr(img_bandArrBIL);

        //BSQ转为BIP
        int[][][] img_bandArrBIP = img.BSQtoBIP(img_bandArrBSQ);
        System.out.println("BIP的存储格式");
        img.printBandArr(img_bandArrBIP);

        //BIL转为BSQ
        int[][][] img_bandArrBSQ_1 = img.BILtoBSQ(img_bandArrBIL);
        System.out.println("BSQ的存储格式");
        img.printBandArr(img_bandArrBSQ_1);

        //BIL转为BIP
        int[][][] img_bandArrBIP_1 = img.BILtoBIP(img_bandArrBIL);
        System.out.println("BIP的存储格式");
        img.printBandArr(img_bandArrBIP_1);

        //BIP转为BSQ
        int[][][] imgBandArrBSQ_2 = img.BIPtoBSQ(img_bandArrBIP);
        System.out.println("BSQ的存储格式");
        img.printBandArr(imgBandArrBSQ_2);

        //BIP转为BIL
        int[][][] imgBandArrBIL_2 = img.BIPtoBIL(img_bandArrBIP);
        System.out.println("BIL的存储格式");
        img.printBandArr(imgBandArrBIL_2);
    }
}

三、实验结果

仅展示BSQ转BIL,BIP的测试结果

图像的元数据

​​

①读取为BSQ格式的存储格式

②BSQ转BIL

③BSQ转BIP 


http://www.niftyadmin.cn/n/5450032.html

相关文章

【ARM64 常见汇编指令学习 23 -- ARMv8/v9 出入栈介绍】

文章目录 ARMv8/v9 出入栈举例 ARMv8/v9 出入栈举例 实现一个 C函数调用汇编函数A&#xff0c;然后汇编函数A先进行入栈然后再去读取寄存器MPIDR_EL1的值到X0中最后再进行出栈操作再ret 为了实现这个需求&#xff0c;我们需要创建一个 C 函数&#xff0c;它将调用一个汇编函数…

【串口开发】android 智能设备开发 知识笔记

1.一般的波特率选择115200,自己玩的可以用9600等随便的 2.为了android方便操作,引入了 implementation com.licheedev:android-serialport:2.1.3包。 不然就得手写了,比如像这样 ,打开串口监听 // 打开串口boolean openSerialPort = mSerialPortManager.setOnOpenSerial…

Pandas------操作CSV文件

介绍 CSV&#xff08;Comma-Separated Values&#xff0c;逗号分隔值&#xff0c;有时也称为字符分隔值&#xff0c;因为分隔字符也可以不是逗号&#xff09;&#xff0c;其文件以纯文本形式存储表格数据&#xff08;数字和文本&#xff09;。 CSV 是一种通用的、相对简单的文…

JavaSE—异常处理深入了解(一)

本章学习内容&#xff1a;使用异常处理机制&#xff0c;对程序运行过程中出现的异常情况进行捕捉并处理. 目录 &#x1f4cc; Java异常概述 &#x1f4cc; Java异常体系结构 &#x1f4cc; 常见的异常 &#x1f4cc; 异常处理 &#x1f4cc; Java异常概述 ○ 异常的概念&…

Linux curl 类似 postman 直接发送 get/post 请求

linux 命令基础汇总 命令&基础描述地址linux curl命令行直接发送 http 请求Linux curl 类似 postman 直接发送 get/post 请求linux ln创建链接&#xff08;link&#xff09;的命令创建链接&#xff08;link&#xff09;的命令linux linklinux 软链接介绍linux 软链接介绍l…

Zabbix 配置使用

目录 配置流程 添加组机组 添加模板 添加主机 配置图形 配置大屏 Monitoring 配置地图 最新数据 故障 使用IT服务 使用报表 资产管理 全局搜索 导入导出 用户权限 用户组权限 用户 匿名用户 调试模式 与 LDAP 对接 维护模式 故障确认 批量更新 配置流程…

电源缓启动(软起动)原理分享

谈起电源的缓启动(软起动),我们都知道现在大多数电子系统都要支持热插拔功能。所谓热插拔,也就是在系统正常工作时,带电对系统的某个单元进行插拔操作,且不对系统产生任何影响。 一、热插拔对系统的影响主要有两方面 其一,热插拔时,连接器的机械触点在接触瞬间会出现…

esp32CAM环境搭建(arduino+MicroPython+thonny+固件)

arduino ide 开发工具 arduino版本&#xff1a;1.8.19 arduino ide 中文设置&#xff1a;​ file >> preferences >> ​ arduino IDE 获取 ESP32 开发环境&#xff1a;打开 Arduino IDE &#xff0c;找到 文件>首选项 ,将 ESP32 的配置链接填入附加开发板管理网…