(二)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 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/487018.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【中间件】docker数据卷

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;中间件 ⛺️稳中求进&#xff0c;晒太阳 1.数据卷&#xff08;容器数据管理&#xff09; 修改nginx的html页面时&#xff0c;需要进入nginx内部。并且因为内部没有编辑器&#xff0c;修改…

手把手教集成环信新版UIKit组件,快速构建Android应用

前言 环信新版UIKit已重磅发布&#xff01;目前包含单群聊UIKit、聊天室ChatroomUIKit&#xff0c;本文详细讲解Android端单群聊UIKit的集成教程。 环信单群聊 UIKit 是基于环信即时通讯云 IM SDK 开发的一款即时通讯 UI 组件库&#xff0c;提供各种组件实现会话列表、聊天界…

网络编程(Internet)

网络编程三要素 在网络通信协议下&#xff0c;不同计算机上运行的程序&#xff0c;可以进行数据传输。 IP地址 要想让网络中的计算机能够互相通信&#xff0c;必须为每台计算机指定一个标识号&#xff0c;通过这个标识号来指定要接收数据的计算机和识别发送的计算机&#xf…

【超图 SuperMap3D】【基础API使用示例】54、超图SuperMap3D -鼠标左键拖拽绘制圆

前言 引擎下载地址&#xff1a;[添加链接描述](http://support.supermap.com.cn/DownloadCenter/DownloadPage.aspx?id2524) 通过左键按下拖拽的方式在地图上进行贴地的圆绘制 完整代码拷贝直接本地运行即可查看效果效果 核心代码 // 绘制圆形 function startDrawCircleHand…

探究橡胶手套与乳胶手套的区别及选择指南

在探寻手部防护的世界里&#xff0c;橡胶手套与乳胶手套各自闪耀着独特的光芒。然而&#xff0c;对于许多人来说&#xff0c;这两者之间的细微差异仍然笼罩在一层迷雾之中。本文将如同一盏明灯&#xff0c;照亮这片迷雾&#xff0c;为您提供一份详尽的选择指南。 首先&#xff…

高性价比 惠海MOS管选型推荐 30V60V100V150V NMOS管和PMOS管

mos管选型建议&#xff1a; 需要抗电流冲击的&#xff0c;普通逻辑开关或者工作频率很低比如50kHZ以内的&#xff0c;电流非常大的情况比如实际工作6A以上的话一般建议选择平面mos管。6A以内的应用&#xff0c;大电流沟槽型mos管即可。 需要高频开关&#xff0c;比如500kHZ以…

2024/3/23打卡数组分割(第14届蓝桥杯)——二项式定理,快速幂

目录 题目 思路 代码 题目 思路 分析该题&#xff0c;要将集合 划分成两个子集 &#xff0c;且两个子集的和都是偶数。 可知&#xff1a;偶数 偶数 偶数&#xff1b;偶数 奇数 奇数&#xff1b;奇数 奇数 偶数&#xff1b; 分析可得&#xff1a;如果该集合的和为奇…

AtCoder Regular Contest 133 B - Dividing Subsequence 复杂版LIS最长上升子序列

B - Dividing Subsequence 题意&#xff1a; 数组a和数组b&#xff0c;找出最长公共子序列&#xff0c;使得每个b[ i ] 都是 a[ i ]的倍数。 思路&#xff1a; AtCoder Regular Contest 133 B(最长上升子序列) C(思维) - 知乎 这种题应把问题转化&#xff0c;把 要找的 和 …

父类子类构造方法调用示例

父类写无参构造&#xff0c;子类不写构造&#xff0c;实例化子类&#xff0c;会同时调用父类构造方法 public class Father {private String name;private int age;public Father() {System.out.println("父类无参构造");}} public class Son extends Father {priva…

prometheus监控oracle

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

element-ui实现各种证件照上传预览下载组件封装,图片上传回显及长宽自定义功能单个图片上传功能附带源码

element-ui实现证件照上传预览下载组件封装 效果&#xff1a; 参数说明 我只写了两个参数&#xff0c;后续有需求再对其组件进行丰富~ 参数说明fileListProp用来存储上传后后端返回的图片UR了uploadUrl图片上传返回的URL后端接口地址widthProp图片上传框的宽度heightProp图片…

人脸聚类原理和算法解释

人脸聚类是指将大量人脸图像根据它们的相似性分组到不同的群集中的过程。人脸聚类通常利用人脸的特征向量表示来度量人脸之间的相似性&#xff0c;并将相似的人脸图像聚集在一起。 以下是人脸聚类的一般原理&#xff1a; 人脸特征提取&#xff1a;对每张人脸图像提取特征向量。…

FPGA结构与片上资源

文章目录 0.总览1.可配置逻辑块CLB1.1 6输入查找表&#xff08;LUT6&#xff09;1.2 选择器&#xff08;MUX&#xff09;1.3 进位链&#xff08;Carry Chain&#xff09;1.4 触发器&#xff08;Flip-Flop&#xff09; 2.可编程I/O单元2.1 I/O物理级2.2 I/O逻辑级 3.布线资源4.其…

为什么静态成员函数不能是虚函数

在面向对象编程中&#xff0c;静态成员函数和虚函数都是常见的概念&#xff0c;但它们之间存在着本质上的差异。由于其特性上的差异&#xff0c;静态成员函数不能声明为虚函数。下面我们来探讨一下为什么静态成员函数不能是虚函数。 我在网上查到最多的说法是静态函数没有this指…

机场防鸟 | 真驱鸟煤气炮驱鸟器产品分析

机场的机坪跑道上&#xff0c;飞机频繁起降&#xff0c;而在机场的上空&#xff0c;偶尔会有几只灵活的小鸟&#xff0c;趁着飞机起降的间隙&#xff0c;在机坪区穿梭&#xff0c;它们或许在寻找食物&#xff0c;或许只是在享受这片广阔的天空。 对于机场驱鸟员来说&#xff0c…

嵌入式学习44-哈希算法和排序算法

Hash 哈希算法&#xff1a; 在记录的 存储位置 和它的 关键字 之间建立一种去特定的对应关系&#xff0c;使得每个关键字key对应一个存储位置&#xff1b; 查找时&#xff0c;根据确定的对应关系&#xff0c;找到给定的 key 的映射。 记录的存储位置 f&a…

vscode安装mysql相关插件

在Visual Studio Code (VSCode) 中安装 MySQL 客户端插件可以让你在 VSCode 中直接连接到 MySQL 数据库&#xff0c;并执行 SQL 查询。以下是如何安装和使用 MySQL 客户端插件的步骤&#xff1a; 1.打开 VSCode。 2.按下 Ctrl Shift X 打开扩展商店&#xff08;或点击侧边栏…

Mysql - date、datetime、timestamp 的区别

date、datetime 的区别 顾名思义&#xff0c;date 日期&#xff0c;datetime 日期时间&#xff0c;所以 date 是 datetime 的日期部分MySQL 以 格式检索和显示 datetime 值 YYYY-MM-DD hh:mm:ss datetime 支持的日期时间范围 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 d…

SpringBoot学习之ElasticSearch下载安装和启动(Windows版)(三十)

本文先写windows下的下载安装和启动,后续有时间再补充其他环境下(Mac、Linux、Docker)的,这里我们后续对ElasticSearch简称为ES,读者习惯这一称呼就好。 一,ES下载 可以百度【ElasticSearch官网】或者直接点击这里的ES官网下载地址:​​​​​ Download Elasticsearch…
最新文章