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

news2024/12/25 8:56:22

环境: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.coloradmin.cn/o/1552254.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

轻松赚钱,精彩生活:上班族副业赚钱新攻略大揭秘!

薪水总是捉襟见肘&#xff0c;每月账单总让人倍感压力。你是否曾在静谧的夜晚&#xff0c;躺在床上&#xff0c;思索如何为家庭多赚一分钱&#xff1f;其实&#xff0c;你并不孤单。在这个充满机遇与挑战的时代&#xff0c;越来越多的人开始寻找副业&#xff0c;以期望让生活更…

【LeetCode热题100】105. 从前序与中序遍历序列构造二叉树(二叉树)

一.题目要求 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点&#xff0c;且不一定经过根节点。 路径和 是路径中各节点值的总和。 给你一个二叉树的根节点 root …

Java基础面试复习

一、java基础 1、jdk、jre、jvm的区别 jdk&#xff1a;Java程序开发工具包。 jre&#xff1a;Java程序运行环境。 jvm&#xff1a;Java虚拟机。 2、一个Java源文件中是否可以包含多个类有什么限制 解&#xff1a;可以包含多个类但是只有一个类生命成public并且要和文件名一致 …

1.java openCV4.x 入门-环境搭建

专栏简介 &#x1f492;个人主页 &#x1f4d6;心灵鸡汤&#x1f4d6;大家 &#x1f4f0;专栏目录 点击上方查看更多内容 环境搭建 一、开发环境二、环境搭建1.openCV安装1.下载程序包 2.程序包安装3.搭建项目 三、非必要资源1.扩展库2.cmake 一、开发环境 开发工具 i…

Python列表、元组、字典及集合

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、列表定义方式&#xff1a; 二、元组1、定义方式&#xff1a;2、元组中的物理存储地址不可修改,如果修改则会报错&#xff0c;但是元组中的列表、字典项等却可以…

Linux第84步_了解Linux中断及其函数

1、中断号 中断号又称中断线&#xff0c;每个中断都有一个中断号&#xff0c;通过中断号即可区分不同的中断。 2、Linux中断API函数 需要包含头文件“#include <linux/interrupt.h>” 1)、在使用某个中断功能的时候&#xff0c;需要执行“申请中断” int request_irq(…

VSCode 如何同步显示网页在手机或者平板上

首先要确保 ①电脑上安装了VsCode ②VsCode安装插件LiveServer 安装成功之后 连续按住 Alt L 、Alt O 会跳转到对应的html页面上 http://127.0.0.1:5500/....... 是这个开头的 然后打开网络 如果桌面有网上邻居的可以直接点桌面的网上邻居 进来找到WLAN这个…

2024年【道路运输企业安全生产管理人员】最新解析及道路运输企业安全生产管理人员证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 道路运输企业安全生产管理人员最新解析参考答案及道路运输企业安全生产管理人员考试试题解析是安全生产模拟考试一点通题库老师及道路运输企业安全生产管理人员操作证已考过的学员汇总&#xff0c;相对有效帮助道路运…

InstanceID:zero-shot identity-preserving generation in sconds

1.introduction 个性化图像合成&#xff0c;挑战是生成能够准确保留人物的复杂身份细节的定制图像&#xff0c;这类任务通常称之为控ID型任务&#xff0c;在AI写真&#xff0c;虚拟试穿上都有应用&#xff0c;但是和虚拟试装还是有区别的&#xff0c;但技术路线上其实可以考虑复…

python多进程卡死问题排查

文章目录 背景开发环境启动链路 问题排查pdb调试给文件加共享锁查看进程fdstrace追踪堆栈<br />GDB调试python安装gdb和python-dbgpython-dbg和python版本编译python3.9的dbg文件gdb调试 pytorch多进程卡死问题多进程的fork和spawn模式 其他解决方式使用fastapi自带的bac…

康耐视visionpro-CogDataAnalyTool工具详细说明

CogDataAnalyTool功能: 数据分析工具,统计数据的平均值、标准差、最大值及最小值等。 CogDataAnalyTool操作说明: ①.打开工具栏,双击或点击鼠标拖拽添加CogDataAnalyTool ②.添加通道:根据需要添加多个输入通道,可同时统计多个输入数据。 ③.打开结果栏,点击运行可获…

Linux的学习之路:3、基础指令(2)

一、echo指令 这个指令在上篇文章我也用了但是忘了说了&#xff0c;这个指令的大概用法就是把后面跟的文本等输出在显示器上&#xff0c;如下代码所示打印的“Hello Linux” [rootVM-24-9-centos ~]# echo "Hello Linux" Hello Linux二、输出重定向与输入重定向 着…

金融案例:构建高效统一的需求登记与管理方案

在金融行业数字化转型背景下&#xff0c;银行等金融机构面临着业务模式创新与数据应用的深度融合。业务上所需要的不再是单纯的数据&#xff0c;而是数据背后映射的业务趋势洞察&#xff0c;只有和业务相结合转化为业务度量指标&#xff0c;经过数据分析处理呈现为报表进行展示…

MybatisPlus学习总结

MybatisPlus.xmind 一、MybatisPlus快速入门 1.基本介绍 官网: 简介 | MyBatis-Plus MyBatis Plus是一个基于MyBatis的增强工具&#xff0c;它简化了MyBatis的使用&#xff0c;提供了一系列的增强功能&#xff0c;使开发更加方便快捷。 MyBatis Plus的主要特点包括&#xff…

SQL,group by分组后分别计算组内不同值的数量

SQL&#xff0c;group by分组后分别计算组内不同值的数量 如现有一张购物表shopping 先要求小明和小红分别买了多少笔和多少橡皮&#xff0c;形成以下格式 SELECT name,COUNT(*) FROM shopping GROUP BY name;SELECT name AS 姓名,SUM( CASE WHEN cargo 笔 THEN 1 ELSE 0 END)…

PyPy 通过采用即时编译技术,能够显著提升 Python 代码的执行效率。

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 提升 Python 代码性能至接近 C 语言速度&#xff0c;无需修改源代码。遵循 Python 之父吉多・范罗苏姆的建议&#xff1a;“如果你想让你的代码神奇地运行得更快&#xff0c;你应该试试用 PyPy。” Yo…

二维前缀和与二维差分的表示

前缀和&#xff1a; 上述图片是求范围内的总和的图和公式 上述图片是初始化前缀和数组的图和公式 差分&#xff1a; 上图是差分公式 #include<iostream> #include<climits> #include<algorithm> #include<cstring> #include<cstdio> #include&l…

基于视图能力的县域治理视频基座数字化、智慧化解决方案

一、方案背景 县域治理方案是我国地方治理体系的重要组成部分&#xff0c;对于促进县域经济社会发展、维护社会稳定、推进全面深化改革具有重要意义。随着科技的不断进步&#xff0c;视频监管已经成为了现代社会治理的重要手段之一。县域治理视频监管方案是通过视频监控、数据…

SpringBoot国际化配置流程(超详细)

前言 最新第一次在做SpringBoot的国际化&#xff0c;网上搜了很多相关的资料&#xff0c;都是一些简单的使用例子&#xff0c;达不到在实际项目中使用的要求&#xff0c;因此本次将结合查询的资料以及自己的实践整理出SpringBoot配置国际化的流程。 SpringBoot国际化 "i…

关于svn安装报错2503问题的解决方法

问题&#xff1a; SVN在安装时&#xff0c;一直报错&#xff0c;安装失败 The installer has encountered an unexpected error installing this package.The error code is 2503 权限问题&#xff0c;右键以管理员权限运行。如果你也是像我一样&#xff0c;右键没有以管理员…