(三)单波段图像的伪彩色合成:密度分割

本文介绍了如何在Windows10和IDEA2021.2.3环境中使用GDAL和OpenCV进行单波段图像的伪彩色合成,重点讲解了Mat类的使用以及密度分割原理和代码实现,展示了从灰度图像到伪彩色图像的转换过程。
摘要由CSDN通过智能技术生成

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

系列文章:

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

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

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

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

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

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

(七)图像的均值滤波

(八)图像的中值滤波

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

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

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

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

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


目录

一、认识OpenCV中的Mat类

1、定义及使用方法

2、OpenCV数据类型简介

二、密度分割简介

三、实现过程

1、简述原理

2、代码实现

四、结果

1、输入的灰度图像

2、输出的伪彩色图像


一、认识OpenCV中的Mat类

1、定义及使用方法

Mat可以保存图片,根据所读入的图片为其分配相应大小的内存空间 ,也能利用构造方法自己定义大小,下面是两种创建方法:

Mat mat1 = new Mat(2,2, CvType.CV_8UC3);
Mat mat2 = Imgcodecs.imread("img\\5.png");

用println()试一试打印mat会出现什么

System.out.println(mat1);
System.out.println(mat2);

结果:

 这些代表什么意思呢?

2*2*CV_8UC3:2像素×2像素×数据类型
isCont:是否联系存储
isSubmat:是否为子矩阵
nativeObj:本地对象地址
dataAddr:存储的图片的地址

2、OpenCV数据类型简介

如图(图片来源于CSDN@UU果)

解释2*2*CV_8UC3:下划线后的数字表示图片的位数、数字后的第一个字母表示用于储存像素的类型、后面的符号表示通道数

U:unsigned int ,无符号整型

S:signed int ,有符号整型

F:float,单精度浮点型,float类型本身即有符号

Cx:图像的通道数

 Mat如何存储像素?

System.out.println(mat1.dump());
System.out.println(mat2.dump());

我们所定义的大小是 2行2列,2行即两行,2列就是两个红色矩形框的内容,每一列都包括 B,G,R 】三个通道(3个数据)

 我们之前所输出的信息为20行18列,18列总共有54个通道数,因为图片大小有限,仅展示行数。

二、密度分割简介

单波段图像的伪彩色合成中的密度分割是一种图像处理技术,它通过将单波段图像的不同灰度级别映射到不同的颜色上,来增强图像的视觉效果和信息表达能力

在单波段图像中,所有像素值通常都是灰度级的,这意味着每个像素只有一个亮度值,没有色彩信息。为了提高这些图像的可读性和解释性,可以采用伪彩色合成的方法,其中密度分割是常用的一种技术。

具体来说,密度分割的过程包括以下几个步骤:

1、确定分割级别:根据图像的灰度直方图或其他方法确定分割的级别,即将整个灰度范围分成若干个区间。

2、分配颜色:为每个灰度区间分配一种颜色,这样不同的灰度级别就会对应不同的颜色。

3、应用颜色映射:使用图像处理软件或编程库(如OpenCV)将颜色映射应用到图像上,使得每个像素根据其灰度值显示相应的颜色。

通过这种方式,原本单调的灰度图像就被转换成了色彩丰富的图像,有助于观察者区分不同的特征和细节。这在遥感图像处理、医学影像分析等领域尤为重要,因为人眼对灰度的辨别能力有限,密度分割技术能够利用影像灰度的细微差别来提取特征信息。

三、实现过程

1、简述原理

将单波段的灰度值分级赋予不同的颜色,例如,将灰度值为0-85的赋予B蓝色通道,86-170的赋予G绿色通道,171-255的赋予R红色通道,(怎么分级可按具体情况自己决定),其余两个通道均赋予0值。

2、代码实现

import org.gdal.gdal.Band;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconstConstants;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;

/**
 * @Author: HNUST_jue_chen
 * @Date: 2022/10/22/ 9:44
 * @Attention: 转载, 引用请注明出处
 */

//伪彩色合成
public class CalPseudoColor {
    //加载本地动态链接库
    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    public void graySplit(String path) {

        try {

            gdal.AllRegister();//支持所有驱动
            //以只读方式读取数据存入Dataset类型里
            Dataset dataset = gdal.Open(path, gdalconstConstants.GA_ReadOnly);
            //图像的大小
            int iYSize = dataset.getRasterYSize();
            int iXSize = dataset.getRasterXSize();
            //获取图像的灰度波段
            Band band = dataset.GetRasterBand(1);
            //定义灰度值数组
            int[][] bandArr = new int[iYSize][iXSize];
            //将图像灰度值存入灰度值数组
            for (int i = 0; i < bandArr.length; i++) {
                band.ReadRaster(0, i, iXSize, 1, bandArr[i]);  //一次读取一行灰度值数据
            }

            //灰度图的伪彩色合成(密度分割)
            //OpenCV三通道存储图像的像素是按照B,G,R顺序存储的
            //单通道转多通道算法:
            //原图像灰度值为0-85的赋予B蓝色通道,86-170的赋予G绿色通道,171-255的赋予R红色通道,其余两个通道均赋予0
            //定义二维数组存储三通道的像素值
            int[][] bandArrThreeChannel = new int[iYSize][iXSize * 3];
            for (int i = 0; i < iYSize; i++) {
                for (int j = 0; j < iXSize; j++) {
                    if (bandArr[i][j] >= 170) {
                        //灰度值为171-255的赋予红色通道,其余两个通道赋予0
                        bandArrThreeChannel[i][3 * j + 2] = bandArr[i][j];
                        bandArrThreeChannel[i][3 * j] = 0;
                        bandArrThreeChannel[i][3 * j + 1] = 0;
                    } else if (bandArr[i][j] >= 85) {
                        //灰度值为86-170的赋予绿色通道,其余两个通道赋予0
                        bandArrThreeChannel[i][3 * j + 1] = bandArr[i][j];
                        bandArrThreeChannel[i][3 * j] = 0;
                        bandArrThreeChannel[i][3 * j + 2] = 0;
                    } else if (bandArr[i][j] >= 0) {
                        //灰度值为0-85的赋予蓝色通道,其余两个通道赋予0
                        bandArrThreeChannel[i][3 * j] = bandArr[i][j];
                        bandArrThreeChannel[i][3 * j + 1] = 0;
                        bandArrThreeChannel[i][3 * j + 2] = 0;
                    }
                }
            }

            //定义伪彩色图像的大小及数据类型
            //CV_32SC3:32表示32位,S表示有符号整型,C3表示3个通道
            Mat img_cpc = new Mat(bandArr.length, bandArr[0].length, CvType.CV_32SC3);
            for (int i = 0; i < bandArrThreeChannel.length; i++) {
                img_cpc.put(i, 0, bandArrThreeChannel[i]);  //一次放入一行三通道像素值数据
            }

            //存储伪彩色图像
            Imgcodecs.imwrite("D:\\Project\\IDEA_Project\\RS01\\src\\rs01\\img\\2_cpc.png", img_cpc);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        CalPseudoColor img_gray = new CalPseudoColor();
        img_gray.graySplit("D:\\Project\\IDEA_Project\\RS01\\src\\rs01\\img\\2_gray.png");
    }
}

四、结果

1、输入的灰度图像

2、输出的伪彩色图像

  • 53
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

juechen333

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

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

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

打赏作者

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

抵扣说明:

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

余额充值