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

环境: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编写脚本来实现批量转换。也可以通过数据处理和格式转换的软件或工具。每种格式都有其特定的存储结构和应用场景,在进行格式转换时需要考虑数据的完整性和准确性。由于数据格式的转换可能涉及到大量的数据处理和计算,因此在进行转换时还需要考虑计算机的性能和存储空间等因素。

二、代码实现

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 

  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在IDL中,BSQ(Band SeQuential)矩阵是一种用于存储多波段(多频谱)遥感影像数据的数据结构。它将每个像素的每个波段的值按照波段顺序存储起来,形成一个三维数组。BSQ矩阵的维度通常为[bands, rows, columns],其中bands表示波段数量,rows表示行数,columns表示列数。 BIL(Band InterLeaved by Line)矩阵也用于存储多波段遥感影像数据,但与BSQ矩阵不同的是,BIL矩阵将每个像素的所有波段的值按照像素顺序交错存储,形成一个维数组。BIL矩阵的维度通常为[rows, columns * bands]。 BIP(Band InterLeaved by Pixel)矩阵也用于存储多波段遥感影像数据,与BSQBIL矩阵不同的是,BIP矩阵将每个波段的所有像素的值按照波段顺序交错存储,形成一个维数组。BIP矩阵的维度通常为[rows * columns, bands]。 这三种矩阵的格式存储遥感影像数据时各有优缺点。BSQ矩阵在处理一些基于波段的统计分析和算法时较为高效,因为它在内存中保持了每个波段的连续性。BIL矩阵在进行像素级的遥感影像处理时更为方便。BIP矩阵则更适用于像素级和波段级操作相结合的影像处理任务。 IDL提供了一系列用于读取、写入和处理这些矩阵格式的函数和命令,使用户能够方便地处理和分析遥感影像数据。可以根据具体的需求选择适合的矩阵格式,并利用IDL提供的工具进行相关的数据处理和分析。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

juechen333

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值